public static ProjectionStage CreateInitialProjection(List <PPath> square, Projection p) { ProjectionStage stage = new ProjectionStage(); var corners = new[] { new Vector(0, 0), new Vector(p.SideX, 0), new Vector(p.SideX, p.SideY), new Vector(0, p.SideY) }; var direction = new[] { new Vector(1, 0), new Vector(0, 1), new Vector(-1, 0), new Vector(0, -1) }; for (int i = 0; i < 4; i++) { Rational len = 0; for (int k = 0; k < square[i].edges.Count; k++) { var location = corners[i] + direction[i] * len; var node = square[i].edges[k].From; var pr = new NodeProjection { Original = node, Projection = location }; stage.Nodes.Add(pr); len += square[i].edges[k].Data.length; } } int ptr = 0; foreach (var s in square) { foreach (var e in s.edges) { Segment seg = e.Data.segment; if (!p.AllSegments.Contains(seg)) { seg = new Segment(e.Data.segment.End, e.Data.segment.Start); if (!p.AllSegments.Contains(seg)) { throw new Exception(); } } var begin = stage.Nodes[ptr]; var end = stage.Nodes[(ptr + 1) % stage.Nodes.Count]; ptr++; stage.Edges.Add(new EdgeProjection { begin = begin, end = end, Segments = new List <Segment> { e.Data.segment } }); } } return(stage); }
public static IEnumerable <ProjectionStage> TrySquashPoint(ProjectionCurrentState state, List <AdjoinedSegmentFamilySubset> edges, Projection pr) { var sizes = edges.Select(z => state.nodesMap[z.ProjectedNode].Count).ToArray(); foreach (var p in GetCounting(sizes)) { var proj = new NodeProjection[sizes.Length]; for (int i = 0; i < sizes.Length; i++) { proj[i] = state.nodesMap[edges[i].ProjectedNode][p[i]]; } var vars = Arithmetic.RationalTriangulate(edges[0].family.Segment, edges[1].family.Segment, proj[0].Projection, proj[1].Projection); if (vars == null) { continue; } foreach (var v in vars) { if (v.X < 0 || v.X > pr.SideX || v.Y < 0 || v.Y > pr.SideY) { continue; } var stage = new ProjectionStage(); var sq = new NodeProjection { Original = edges[0].NonProjectedNode, Projection = v }; stage.Nodes.Add(sq); bool ok = true; for (int k = 0; k < sizes.Length; k++) { var len = new Segment(v, proj[k].Projection); if (len.QuadratOfLength != edges[k].family.Segment.QuadratOfLength) { ok = false; break; } stage.Edges.Add(new EdgeProjection { begin = sq, end = proj[k], Segments = edges[k].family.Insides.ToList() }); } if (ok) { yield return(stage); } } } }
public static ProjectionStage AddVeryGoodEdges(Projection p) { var stage = new ProjectionStage(); var ep = p.GetCurrentState(); foreach (var subs in GetAllPossibleSegments(p.SegmentsFamily)) { var startNode = ep.GetNode(subs.Begin)?.NodeNumber; var endNode = ep.GetNode(subs.End)?.NodeNumber; //if ((startNode == 9 && endNode == 8) || (startNode == 8 && endNode == 9)) Console.Write("!"); var res = TryInsertFamily(subs, ep); if (res != null && res.Count != 0) { stage.Edges.AddRange(res); // foreach (var t in res) Console.WriteLine($"{t.begin.Original.NodeNumber} {t.end.Original.NodeNumber}"); return(stage); } } return(null); }
static PointProjectionSolver TrySquashPoint(PointProjectionSolver solver, Projection pr, ProjectionStage stage) { pr.Stages.Push(stage); var res = TryHordEdges(solver, pr); if (res == null) { pr.Stages.Pop(); } return(res); }