PolyLink
A library to allow manipulation of geometry from within Mathematica
 All Classes Namespaces Files Functions Variables Properties
VectorCSPF.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using Wolfram.NETLink;
7 
8 namespace PolyLink
9 {
11  {
12  public VectorCone Cone { get; set; }
13  public Vector Vector { get; set; }
14  }
15 
16  public class VectorCSPF : MathLinked
17  {
18  public Polyhedron Poly { get; private set; }
19  public HalfEdge StartHE { get; private set; }
20  public PointRef StartPoint { get; private set; }
21  public Facet EndFacet { get; private set; }
22  public PointRef EndPoint { get; private set; }
23 
24  public Expr StartGraphics { get; set; }
25 
26  private readonly Dictionary<PointRef, LeaderBoardEntry> _leaderBoard
27  = new Dictionary<PointRef, LeaderBoardEntry>();
28 
29  public VectorCSPF(Polyhedron poly, HalfEdge startHe, Facet endFacet, PointRef start, PointRef end)
30  {
31  Poly = poly;
32  StartHE = startHe;
33  EndFacet = endFacet;
34  EndPoint = end;
35  StartPoint = start;
36  }
37 
38  public bool SeeIfConeHasShortestPath(VectorCone subject, Vector vector, PointRef vert)
39  {
40  var entry = _leaderBoard[vert];
41  if (vector.Length.CompareTo(entry.Vector.Length) < 0)
42  {
43  if (entry.Cone != null)
44  {
45  entry.Cone.Invalidate();
46  }
47  _leaderBoard[vert] = new LeaderBoardEntry{Cone = subject, Vector = vector};
48  return true;
49  }
50  return false;
51  }
52 
53  public Expr ComputeShortestPath()
54  {
55  var infinity = new Vector("{Infinity,Infinity,Infinity}".MsEvalWith());
56  foreach (var point in Poly.HalfEdges.Select(he => he.Start))
57  {
58  _leaderBoard[point] = new LeaderBoardEntry
59  {
60  Cone = null,
61  Vector = infinity,
62  };
63  }
64  _leaderBoard[EndPoint] = new LeaderBoardEntry
65  {
66  Cone = null,
67  Vector = infinity,
68  };
69  var startHEClone = StartHE.FacetCloneWithOriginalOpposites;
70  var startPointClone = StartPoint.DeepClone;
71  startHEClone.Anchor(new[] {startPointClone});
72  var transVector = new Vector(ML["-{0}"].Format(startPointClone.Expr).Eval());
73  startHEClone.NegativeTranslate(transVector);
74 
75  StartGraphics = ML["List"].Bracket(
76  startHEClone.ForceNewFacet.Graphics,
77  ML["Point"].Bracket(PointRef.Origin).Eval()
78  ).Eval();
79 
80  var queue = new Queue<VectorCone>();
81 
82  var hePairs = StartHE.HEsFromHere
83  .NetZip(startHEClone.HEsFromHere, (o, c) => new WorkingCopy<HalfEdge>(o, c));
84 
85  foreach (var pair in hePairs)
86  {
87  var vectToStart = Vector.FromPoints(PointRef.Origin, pair.Copy.Start.Expr);
88  _leaderBoard[pair.Original.Start] = new LeaderBoardEntry
89  {
90  Cone = null,
91  Vector = vectToStart,
92  };
93  var vectToEnd = Vector.FromPoints(PointRef.Origin, pair.Copy.End.Expr);
94 
95  //TODO Find some way to start cones at neighbor facets for these cases
96  if ((bool) ML["{0} == {1}"].Format(vectToStart.Expr, "{0,0,0}").EvalObject())
97  {
98  continue;
99  }
100  if ((bool) ML["{0} == {1}"].Format(vectToEnd.Expr, "{0,0,0}").EvalObject())
101  {
102  continue;
103  }
104 
105 
106  IEnumerable<PointRef> newEndPoint = null;
107  var newHE = new WorkingCopy<HalfEdge>(pair.Original.Opposite,
108  pair.Original.Opposite.FacetCloneWithOriginalOpposites);
109  if (newHE.Original.Facet == EndFacet)
110  {
111  newEndPoint = new[] {EndPoint.DeepClone};
112  }
113  newHE.Copy.Opposite = pair.Copy;
114  newHE.Copy.Unfold(newEndPoint);
115  newHE.Copy.Opposite = pair.Original;
116  PointRef endPoint = (newEndPoint != null) ? newEndPoint.First() : null;
117 
118  queue.Enqueue(
119  new VectorCone(
120  parent: null,
121  currentEdge: newHE,
122  cspf: this,
123  lBind: vectToStart,
124  rBind: vectToEnd,
125  transformedEndPoint: endPoint
126  )
127  );
128  }
129  //Put the loop here!!
130  long loopNumber = 0;
131  while (queue.Count > 0)
132  {
133  loopNumber++;
134  if (loopNumber == 10)
135  {
136  int x = 0;
137  }
138 
139  var cone = queue.Dequeue();
140 
141  if ((bool) ML["{0}[[3]] < -.0001 || {0}[[3]] > .0001"].Format(cone.CurrentEdge.Copy.Start.Expr).EvalObject())
142  {
143  throw new Exception("Relative source is not on plane");
144  }
145 
146  if (!cone.Valid)
147  continue;
148  var splitCones = cone.TryExtend();
149  if (!cone.Valid)
150  continue;
151  if (splitCones.Left != null)
152  {
153  if ((bool)ML["{0} < {1}"]
154  .Format(cone.Aperture, splitCones.Left.Aperture)
155  .EvalObject())
156  {
157  Console.WriteLine("Child larger than parent");
158  }
159  queue.Enqueue(splitCones.Left);
160  }
161  if (splitCones.Right != null)
162  {
163  if ((bool)ML["{0} < {1}"]
164  .Format(cone.Aperture, splitCones.Right.Aperture)
165  .EvalObject())
166  {
167  Console.WriteLine("Child larger than parent");
168  }
169  queue.Enqueue(splitCones.Right);
170  }
171  }
172  return _leaderBoard[EndPoint].Vector.Expr;
173  }
174 
175 
176  }
177 }
Definition: VectorCSPF.cs:10
VectorCone Cone
Definition: VectorCSPF.cs:12