public int NextRight(int rightIndex, List <AdventureLandLibrary.Geometry.LineD> portals) { var curPoint = portals[rightIndex].P1; if (rightIndex < portals.Count - 1) { int nextIndex = rightIndex + 1; AdventureLandLibrary.Geometry.PointD nextPoint = portals[nextIndex].P1; //while (curPoint.X == nextPoint.X && curPoint.Y == nextPoint.Y && nextIndex < portals.Count - 1) //{ // nextIndex++; // nextPoint = portals[nextIndex].P2; //} return(nextIndex); } else { return(rightIndex); } }
public List <AdventureLandLibrary.Geometry.Point> FunnelSmooth(List <AdventureLandLibrary.Geometry.GraphNode> path, AdventureLandLibrary.Geometry.Point startPoint, AdventureLandLibrary.Geometry.Point endPoint) { if (path.Count > 2) { var offsetEndpoint = new AdventureLandLibrary.Geometry.Point(endPoint.X + currentMap.OffsetX, endPoint.Y + currentMap.OffsetY); List <AdventureLandLibrary.Geometry.Point> newPath = new List <AdventureLandLibrary.Geometry.Point>(); List <AdventureLandLibrary.Geometry.LineD> portals = new List <AdventureLandLibrary.Geometry.LineD>(); for (var i = 0; i < path.Count - 1; i++) { portals.Add(path[i].GetPortal(path[i + 1])); } var ending = path[path.Count - 1].GetNonPortal(path[path.Count - 2], offsetEndpoint); portals.AddRange(ending); var portalsToDelete = new List <AdventureLandLibrary.Geometry.LineD>(); for (var i = 0; i < portals.Count; i++) { var portal = portals[i]; var p1Link = portals.Where(p => (p.P1.X == portal.P1.X && p.P1.Y == portal.P1.Y) || (p.P2.X == portal.P1.X && p.P2.Y == portal.P1.Y)).ToList(); var p2Link = portals.Where(p => (p.P1.X == portal.P2.X && p.P1.Y == portal.P2.Y) || (p.P2.X == portal.P2.X && p.P2.Y == portal.P2.Y)).ToList(); if ((p1Link.Count == 1 || p2Link.Count == 1) && (i != 0 && i != portals.Count - 1)) { //portalsToDelete.Add(portal); } } foreach (var portal in portalsToDelete) { portals.Remove(portal); } AdventureLandLibrary.Geometry.PointD currentNode = new AdventureLandLibrary.Geometry.PointD(startPoint.X + currentMap.OffsetX, startPoint.Y + currentMap.OffsetY); newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY)); int funnelLeftIndex = 1; int funnelRightIndex = 1; int curFunnelLeftIndex = 1; int curFunnelRightIndex = 1; AdventureLandLibrary.Geometry.LineD funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[0].P2); AdventureLandLibrary.Geometry.LineD funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[0].P1); DrawLine(funnelLeft, Brushes.Cyan, 2); DrawLine(funnelRight, Brushes.Purple, 2); int leftSide = 0; int rightSide = 1; AdventureLandLibrary.Geometry.PointD lastPoint = new AdventureLandLibrary.Geometry.PointD(offsetEndpoint.X, offsetEndpoint.Y); int count = 0; while (funnelLeftIndex < portals.Count && funnelRightIndex < portals.Count && !(funnelLeft.P2.X == lastPoint.X && funnelLeft.P2.Y == lastPoint.Y) && !(funnelRight.P2.X == lastPoint.X && funnelRight.P2.Y == lastPoint.Y)) { var prevLeftPoint = portals[funnelLeftIndex].P2; if (leftSide == 0 && funnelLeftIndex > 0) { prevLeftPoint = portals[funnelLeftIndex - 1].P2; } var prevRightPoint = portals[funnelRightIndex].P1; if (rightSide == 0 && funnelRightIndex > 0) { prevRightPoint = portals[funnelRightIndex - 1].P1; } var newFunnelLeftIndex = funnelLeftIndex + leftSide; var newFunnelRightIndex = funnelRightIndex + rightSide; if (newFunnelLeftIndex > portals.Count - 1) { newFunnelLeftIndex = portals.Count - 1; } if (newFunnelRightIndex > portals.Count - 1) { newFunnelRightIndex = portals.Count - 1; } curFunnelLeftIndex = curFunnelLeftIndex + leftSide; curFunnelRightIndex = curFunnelRightIndex + rightSide; if (curFunnelLeftIndex > portals.Count - 1) { curFunnelLeftIndex = portals.Count - 1; } if (curFunnelRightIndex > portals.Count - 1) { curFunnelRightIndex = portals.Count - 1; } var actualLeftPoint = portals[newFunnelLeftIndex].P2; var actualRightPoint = portals[newFunnelRightIndex].P1; var leftPoint = portals[curFunnelLeftIndex].P2; var rightPoint = portals[curFunnelRightIndex].P1; var insideFunnel = false; var dirLeftLeft = funnelLeft.Direction(leftPoint); var dirRightRight = funnelRight.Direction(rightPoint); var leftIsRightOfLeft = funnelLeft.Direction(leftPoint) <= 0; var rightIsLeftOfRight = funnelRight.Direction(rightPoint) >= 0; var dirLeftRight = funnelRight.Direction(leftPoint); var dirRightLeft = funnelLeft.Direction(rightPoint); var leftIsLeftOfRight = funnelRight.Direction(leftPoint) >= 0; var rightIsRightOfLeft = funnelLeft.Direction(rightPoint) <= 0; if (leftIsRightOfLeft && rightIsLeftOfRight && leftIsLeftOfRight && rightIsRightOfLeft) { insideFunnel = true; } if (!insideFunnel) { if (!leftIsLeftOfRight) { currentNode = new AdventureLandLibrary.Geometry.PointD(portals[funnelRightIndex].P1.X, portals[funnelRightIndex].P1.Y); newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY)); //funnelLeftIndex = newFunnelLeftIndex; //funnelRightIndex = newFunnelLeftIndex; var minIndex = Math.Min(newFunnelLeftIndex, newFunnelRightIndex); var newFRight = NextRight(minIndex, portals); var newFLeft = NextLeft(minIndex, portals); var maxPortal = Math.Max(newFRight, newFLeft); funnelLeftIndex = maxPortal; funnelRightIndex = maxPortal; funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[maxPortal].P2); funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[maxPortal].P1); curFunnelLeftIndex = maxPortal; curFunnelRightIndex = maxPortal; DrawLine(funnelLeft, Brushes.Cyan, 3); DrawLine(funnelRight, Brushes.Purple, 3); } else if (!rightIsRightOfLeft) { currentNode = new AdventureLandLibrary.Geometry.PointD(portals[funnelLeftIndex].P2.X, portals[funnelLeftIndex].P2.Y); newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY)); //funnelLeftIndex = newFunnelRightIndex; //funnelRightIndex = newFunnelRightIndex; //curFunnelLeftIndex = funnelLeftIndex; //curFunnelRightIndex = funnelRightIndex; var minIndex = Math.Min(newFunnelLeftIndex, newFunnelRightIndex); var newFRight = NextRight(minIndex, portals); var newFLeft = NextLeft(minIndex, portals); var maxPortal = Math.Max(newFRight, newFLeft); funnelLeftIndex = maxPortal; funnelRightIndex = maxPortal; funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[maxPortal].P2); funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[maxPortal].P1); curFunnelLeftIndex = maxPortal; curFunnelRightIndex = maxPortal; DrawLine(funnelLeft, Brushes.Cyan, 3); DrawLine(funnelRight, Brushes.Purple, 3); } else if (rightIsLeftOfRight) { funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, rightPoint); //funnelRightIndex = newFunnelRightIndex; //curFunnelRightIndex = newFunnelRightIndex; //DrawLine(funnelLeft, Brushes.Cyan, 3); //DrawLine(funnelRight, Brushes.Purple, 3); } else if (leftIsRightOfLeft) { funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, leftPoint); //funnelLeftIndex = newFunnelLeftIndex; //curFunnelLeftIndex = newFunnelRightIndex; DrawLine(funnelLeft, Brushes.Cyan, 3); DrawLine(funnelRight, Brushes.Purple, 3); } //else if (!rightIsLeftOfRight) //{ // currentNode = new AdventureLandLibrary.Geometry.PointD(prevRightPoint.X, prevRightPoint.Y); // newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY)); // funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, leftPoint); // funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, rightPoint); // DrawLine(funnelLeft, Brushes.Cyan, 2); // DrawLine(funnelRight, Brushes.Purple, 2); //} //else if (!leftIsRightOfLeft) //{ // currentNode = new AdventureLandLibrary.Geometry.PointD(prevLeftPoint.X, prevLeftPoint.Y); // newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY)); // funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, leftPoint); // funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, rightPoint); // DrawLine(funnelLeft, Brushes.Cyan, 2); // DrawLine(funnelRight, Brushes.Purple, 2); //} } else { var newfunnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, leftPoint); var newfunnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, rightPoint); funnelLeftIndex = newFunnelLeftIndex; funnelRightIndex = newFunnelRightIndex; funnelLeft = newfunnelLeft; funnelRight = newfunnelRight; curFunnelLeftIndex = funnelLeftIndex; curFunnelRightIndex = funnelRightIndex; //DrawLine(funnelLeft, Brushes.Cyan); //DrawLine(funnelRight, Brushes.Purple); } leftSide++; rightSide++; if (leftSide > 1) { leftSide = 0; } if (rightSide > 1) { rightSide = 0; } count++; } newPath.Add(new AdventureLandLibrary.Geometry.Point(endPoint.X, endPoint.Y)); return(newPath); } else { List <AdventureLandLibrary.Geometry.Point> newPath = new List <AdventureLandLibrary.Geometry.Point>(); newPath.Add(startPoint); newPath.Add(endPoint); return(newPath); } }