// Create area segments borders private void CreateAreaBlockerLines() { foreach (var edge in VoronoiDiagram.Edges) { if (!edge.Visible()) { continue; } int leftAreaSegmentID = _siteAreaSegmentMap[edge.LeftSite.Coord]; int rightAreaSegmentID = _siteAreaSegmentMap[edge.RightSite.Coord]; AreaSegment leftAreaSegment = AreaSegmentGraph.GetNodeData(leftAreaSegmentID); AreaSegment rightAreaSegment = AreaSegmentGraph.GetNodeData(rightAreaSegmentID); var leftNeighborhood = AreaSegmentGraph.GetNeighbours(leftAreaSegmentID); if (leftAreaSegmentID == rightAreaSegmentID || leftAreaSegment.Type == AreaSegment.EAreaSegmentType.Border || rightAreaSegment.Type == AreaSegment.EAreaSegmentType.Border || !leftNeighborhood.Contains(rightAreaSegmentID) || AreaSegmentGraph.GetEdgeValue(leftAreaSegmentID, rightAreaSegmentID) != (int)AreaSegment.EAreaSegmentEdgeType.NonNavigable) { continue; } var p0 = edge.ClippedEnds[LR.LEFT].ToUnityVector2(); var p1 = edge.ClippedEnds[LR.RIGHT].ToUnityVector2(); var segment = new[] { p0, p1 }; AreaBlockerLines.Add(segment); } }
// Create path lines private void CreatePathLines() { var mainPath = new List <Vector2[]>(); var allSidePaths = new List <Vector2[]>(); foreach (var graphEdge in AreaSegmentGraph.GetAllEdges()) { int edgeValue = AreaSegmentGraph.GetEdgeValue(graphEdge); Vector2 leftCenter = _areaSegmentCenterMap[graphEdge.x]; Vector2 rightCenter = _areaSegmentCenterMap[graphEdge.y]; Vector2f leftSite = new Vector2f(leftCenter); Vector2f rightSite = new Vector2f(rightCenter); Vector2 edgeCrossing = Vector2.zero; // Get the middle point of the crossing voronoi edge -> ensure crossable point foreach (var e in VoronoiDiagram.Edges) { if (!e.Visible()) { continue; } if (e.LeftSite.Coord == leftSite && e.RightSite.Coord == rightSite || e.LeftSite.Coord == rightSite && e.RightSite.Coord == leftSite) { edgeCrossing = (e.ClippedEnds[LR.LEFT] + e.ClippedEnds[LR.RIGHT]).ToUnityVector2() / 2f; break; } } // Add path lines switch (edgeValue) { case (int)AreaSegment.EAreaSegmentEdgeType.MainPath: mainPath.Add(new[] { leftCenter, edgeCrossing }); mainPath.Add(new[] { edgeCrossing, rightCenter }); break; case (int)AreaSegment.EAreaSegmentEdgeType.SidePath: allSidePaths.Add(new[] { leftCenter, edgeCrossing }); allSidePaths.Add(new[] { edgeCrossing, rightCenter }); break; } } // Separate side paths var sidePathsList = new List <List <Vector2[]> >(); while (allSidePaths.Count > 0) { var sidePath = new List <Vector2[]>(); sidePath.Add(allSidePaths[0]); allSidePaths.Remove(sidePath[0]); bool found = true; while (found) { found = false; for (int i = 0; i < allSidePaths.Count; i++) { var line = allSidePaths[i]; var predicate = new Func <Vector2[], bool>(a => a[0] == line[0] || a[0] == line[1] || a[1] == line[0] || a[1] == line[1]); if (sidePath.Any(predicate)) { found = true; sidePath.Add(line); allSidePaths.Remove(line); break; } } } sidePathsList.Add(sidePath); } MainPathLines = CreateBezierPath(mainPath); foreach (var sidePath in sidePathsList) { SidePathLines.AddRange(CreateBezierPath(sidePath)); } }