PolyLink
A library to allow manipulation of geometry from within Mathematica
All Classes Namespaces Files Functions Variables Properties
HalfEdge_old.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using Wolfram.NETLink;
5 
6 namespace MathPolyLib
7 {
11  //public class HalfEdge : MathLinked
12  //{
13  /*
19  public HalfEdge(PointRef start, PointRef end)
20  {
21  _start = start;
22  _end = end;
23  }
24 
25  public Facet Facet { get; set; }
26 
30  public EndPointPacket EndPointPacket
31  {
32  get
33  {
34  return new EndPointPacket(Start, End);
35  }
36  }
37 
41  public EndPointPacket OppositesEndPointPacket
42  {
43  get
44  {
45  return EndPointPacket.Opposite;
46  }
47  }
48 
49  public PointRef Start
50  {
51  get { return _start; }
52  set { _start = value; }
53  }
54 
55  public PointRef End
56  {
57  get { return _end; }
58  set { _end = value; }
59  }
60 
61  protected PointRef _start;
62  protected PointRef _end;
63 
64  protected HalfEdge _opposite;
65 
69  public HalfEdge Opposite
70  {
71  get { return _opposite; }
72  set
73  {
74  _opposite = value;
75  }
76  }
77 
78  protected HalfEdge _next;
79  protected HalfEdge _prev;
80 
84  public HalfEdge Next
85  {
86  get { return _next; }
87  }
88 
92  public HalfEdge Prev
93  {
94  get { return _prev; }
95  }
96 
97  /*private List<HalfEdge> InsertAfter(HalfEdge he)
98  {
99  //Acting upon this
100  var oldNext = _next;
101  _next = he;
102 
103  //Acting upon he
104  var retList = new List<HalfEdge>();
105  if (he._next != null)
106  {
107  he._next._prev = null;
108  retList.Add(he._next);
109  }
110  if (he._prev != null)
111  {
112  he._prev._next = null;
113  retList.Add(he._prev);
114  }
115  he._next = oldNext;
116  he._prev = this;
117  return retList;
118  }
119 
123  public IEnumerable<FoldingHalfEdge> HEsFromHere
124  {
125  get
126  {
127  yield return this;
128  var he = this.Next;
129  while (he != this)
130  {
131  yield return he;
132  he = he.Next;
133  }
134  }
135  }
136 
137  public IEnumerable<HalfEdge> HEsFromHereReversed
138  {
139  get
140  {
141  yield return this;
142  var he = this.Prev;
143  while (he != this)
144  {
145  yield return he;
146  he = he.Prev;
147  }
148  }
149  }
150 
154  public Expr AsVectorExpr
155  {
156  get { return EndPointPacket.AsVectorExpr; }
157  }
158 
162  public Plane Plane
163  {
164  get
165  {
166  Expr point = Start.Point;
167  Expr normal = ML["Normalize[Cross[{0},{1}]]"].Format(this.AsVectorExpr, Next.AsVectorExpr).FullSimplify().Eval();
168  return new Plane(point, normal);
169  }
170  }
171 
175  public Expr DotOpposite
176  {
177  get { return ML["Dot[{0},{1}]"].Format(this.Plane.Normal, Opposite.Plane.Normal).Eval(); }
178  }
179 
184  public HalfEdge[] DetourToVertex(PointRef p)
185  {
186  var ret = new HalfEdge[2];
187  var outHE = new HalfEdge(End, p)
188  {
189  Facet = Facet
190  };
191  var backHE = new HalfEdge(p, End)
192  {
193  Facet = Facet
194  };
195  outHE.Opposite = backHE;
196  backHE.Opposite = outHE;
197 
198  var oldNext = _next;
199  _next = outHE;
200  outHE._prev = this;
201  outHE._next = backHE;
202  backHE._prev = outHE;
203  backHE._next = oldNext;
204 
205  ret[0] = outHE;
206  ret[1] = backHE;
207  return ret;
208  }
209 
215  public Dictionary<HalfEdge, HalfEdge> LinkNext(HalfEdge he)
216  {
217  var d = new Dictionary<HalfEdge, HalfEdge>();
218  d[this] = Next;
219  d[he] = he.Prev;
220  _next = he;
221  he._prev = this;
222  return d;
223  }
224 
228  public bool OppIsNull
229  {
230  get { return Opposite == null; }
231  }
232 
236  public void MergeAcross()
237  {
238  var prev = Prev;
239  prev.LinkNext(Opposite.Next);
240  Opposite.Prev.LinkNext(Next);
241  Opposite.Facet.Head = null;
242  foreach (var halfEdge in prev.HEsFromHere)
243  {
244  halfEdge.Facet = Facet;
245  }
246  }
247 
248  public override string ToString()
249  {
250  return String.Format("[{0} to {1}]", Start, End);
251  }
252 
256  public IEnumerable<HalfEdge> CycleAboutEndPoint
257  {
258  get
259  {
260  yield return this;
261  var he = this.Next.Opposite;
262  while (he != this)
263  {
264  yield return he;
265  he = he.Next.Opposite;
266  }
267  }
268  }
269 
273  public Expr DotNext
274  {
275  get { return ML["Dot"].Bracket(this.AsVectorExpr, this.Next.EndPointPacket.Opposite.AsVectorExpr).Eval(); }
276  }
277 
281  public Expr AngleToNext
282  {
283  get
284  {
285  return ML["ArcCos[{0}] / ({1} * {2})"].Format(this.DotNext, this.EndPointPacket.Magnitude,
286  this.Next.EndPointPacket.Magnitude).Eval();
287  }
288  }
289 
293  public Expr SumAngles
294  {
295  get
296  {
297  return this.CycleAboutEndPoint.Select(he => he.AngleToNext).Aggregate((a1, a2) => ML["{0} + {1}"].Format(a1,a2).Eval());
298  }
299  }
300 
301  public FoldingHalfEdge AsFoldingHalfEdge
302  {
303  get { return (this as FoldingHalfEdge); }
304  }
305 
309  public Expr Curvature
310  {
311  get { return ML["2*Pi - {0}"].Format(SumAngles).Eval(); }
312  }
313 
314  public virtual Expr Graphics
315  {
316  get { return null; }
317  }
318 
319  public Expr Highlight
320  {
321  get { return ML["GraphicsGroup[ {{ Thick, Red, Arrow[ {{ {0},{1} }} ] }} ]"].Format(Start.Point, End.Point).Eval(); }
322  }
323 
324  //Static methods
325 
326  private static readonly HalfEdge littleLine = new HalfEdge(PointRef.OriginRef, PointRef.Ref100);
327  private static readonly HalfEdge line2 = new HalfEdge(PointRef.Ref100, PointRef.Ref010);
328  private static readonly HalfEdge line3 = new HalfEdge(PointRef.Ref010, PointRef.OriginRef);
329 
333  public static HalfEdge LittleLine
334  {
335  get { return littleLine; }
336  }
337 
341  public static HalfEdge Facetable
342  {
343  get
344  {
345  if (LittleLine.Next == null)
346  {
347  LittleLine.LinkNext(line2);
348  line2.LinkNext(line3);
349  line3.LinkNext(LittleLine);
350  }
351  return LittleLine;
352  }
353  }
354 
355  //TODO this function doesn't work. And we don't run it very often.
356  public virtual HalfEdge FacetRingClone
357  {
358  get
359  {
360  throw new NotImplementedException();
361  /*
362  var cloneRing = HEsFromHere.Select(he => he.ShallowClone).Skip(1).ToList();
363  var prev = this.ShallowClone;
364  var myClone = prev;
365 
366  foreach (var he in cloneRing.Concat(new[] {myClone}))
367  {
368  he.Start = he.Start.DeepClone;
369  he.End = he.End.DeepClone;
370  he._prev = prev;
371  prev._next = he;
372  }
373  return myClone;
374  }
375  }
376 
377  protected virtual HalfEdge ShallowClone
378  {
379  get
380  {
381  throw new NotImplementedException();
382  /*
383  var n = new HalfEdge(Start, End){
384  _next = Next,
385  _prev = Prev,
386  _opposite = null};
387  return n;
388  }
389  }
390 
391  public Expr NormalGraphics
392  {
393  get { return ML["GraphicsGroup[ {{Purple, Arrow[ {{ {0}, {0} + {1} }} ] }} ]"].Format(End.Point, Plane.Normal).Eval(); }
394  }
395  */
396  //}
397 }