PolyLink
A library to allow manipulation of geometry from within Mathematica
Main Page
Packages
Classes
Files
File List
All
Classes
Namespaces
Files
Functions
Variables
Properties
Cone2.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
Defunct
9
{
10
/*public class Cone : MathLinked
11
{
12
private bool _valid;
13
14
private readonly Cone _parent;
15
private Cone _left;
16
private Cone _right;
17
private readonly Expr _relativeSource;
18
private readonly Expr _relativeAngleL;
19
private readonly Expr _relativeAngleR;
20
private readonly Expr _absoluteSourceToCorner;
21
private readonly ConvexShortestPathFinder _cspf;
22
private readonly Expr _anchorMatrix;
23
24
private readonly HalfEdge _currentCrossedHalfEdge;
25
private readonly HalfEdge _workingHECopy;
26
27
public string Tag { get; set; }
28
public Facet CurrentFacet
29
{
30
get { return _currentCrossedHalfEdge.Facet; }
31
}
32
public string CurrentFacetTag
33
{
34
get { return _currentCrossedHalfEdge.Facet.Tag; }
35
}
36
47
public Cone(Cone parent, Expr relativeAngleL, Expr relativeAngleR,
48
Expr absoluteSourceToCorner, Expr relativeSource,
49
HalfEdge currentCrossedHalfEdge,
50
ConvexShortestPathFinder cspf)
51
{
52
_parent = parent;
53
_relativeAngleL = relativeAngleL;
54
_relativeAngleR = relativeAngleR;
55
_relativeSource = relativeSource;
56
_currentCrossedHalfEdge = currentCrossedHalfEdge;
57
_cspf = cspf;
58
_absoluteSourceToCorner = absoluteSourceToCorner;
59
_workingHECopy = _currentCrossedHalfEdge.FacetRingClone;
60
_valid = true;
61
_anchorMatrix = _workingHECopy.AnchorMatrix;
62
63
_workingHECopy.Anchor();
64
}
65
66
public Cone Parent
67
{
68
get { return _parent; }
69
}
70
71
public Cone Left
72
{
73
get { return _left; }
74
}
75
76
public Cone Right
77
{
78
get { return _right; }
79
}
80
81
public bool Valid
82
{
83
get { return _valid; }
84
}
85
86
public void Invalidate()
87
{
88
if (Left != null)
89
{
90
Left.Invalidate();
91
}
92
if (Right != null)
93
{
94
Right.Invalidate();
95
}
96
_valid = false;
97
}
98
99
public Tuple<Cone, Cone> TryExtend()
100
{
101
switch (CheckIfShortestPath())
102
{
103
case ShortestPathResult.Shortest:
104
return new Tuple<Cone, Cone>(null, null);
105
case ShortestPathResult.NotShortest:
106
Invalidate(); return new Tuple<Cone, Cone>(null, null);
107
case ShortestPathResult.NotViable:
108
break;
109
default:
110
throw new ArgumentOutOfRangeException();
111
}
112
113
var oppositeVertex = _currentCrossedHalfEdge.Next.End;
114
115
var sourceToOppEpp = (new EndPointPacket(new PointRef(RelativeSource), TransformOppositeVertex));
116
var sourceToOpp = sourceToOppEpp.AsVector;
117
118
//TODO originToSource might be the opposite of what value we need in some uses. :/ :help:
119
var originToSource = ML["- {0}"].Format(RelativeSource).Eval();
120
121
var splitAngle = SignedAngle(originToSource, sourceToOpp);
122
123
var lCompare = _relativeAngleL.CompareTo(splitAngle);
124
var rCompare = _relativeAngleR.CompareTo(splitAngle);
125
126
if (rCompare > lCompare)
127
{
128
throw new Exception("Right angle is left of left angle");
129
}
130
if (lCompare == 0 || lCompare != rCompare)
131
{
132
if (!_cspf.SeeIfConeHasShortestPath(this, sourceToOppEpp.Magnitude, oppositeVertex))
133
{
134
Invalidate();
135
return new Tuple<Cone, Cone>(null, null);
136
}
137
}
138
//TODO the angles need to be absolute, not relative. Otherwise this whole thing is useless!
139
//I shouldn't be using the split angle all the time, some times it is outside of the bounds of angleL and angleR
140
if (lCompare.EqualsAny(0, 1))
141
{
142
var leftHalfEdge = _currentCrossedHalfEdge.Prev.Opposite;
143
144
var rightAngle = ML["Max"].Bracket(splitAngle, _relativeAngleR).Eval();
145
146
_left = new Cone(parent: this,
147
relativeSource: TransformSourceLeft,
148
currentCrossedHalfEdge: leftHalfEdge,
149
relativeAngleL: _relativeAngleL,
150
relativeAngleR: rightAngle,
151
absoluteSourceToCorner: _absoluteSourceToCorner,
152
cspf: _cspf)
153
{Tag = Tag + " Left"};
154
}
155
if (rCompare.EqualsAny(0, -1))
156
{
157
var newAbsolute = ML["{0} + {1}"].Format(_absoluteSourceToCorner, splitAngle).Eval();
158
159
160
var rightHalfEdge = _currentCrossedHalfEdge.Next.Opposite;
161
162
var leftAngle = ML["Min"].Bracket(
163
ML["{0}-{1}"].Format(_relativeAngleL,splitAngle).Eval(),
164
"0").Eval();
165
166
Expr rightAngle = ML["{0} - {1}"].Format(_relativeAngleR, splitAngle).Eval();
167
168
_right = new Cone(parent: this,
169
relativeSource: TransformSourceRight,
170
currentCrossedHalfEdge: rightHalfEdge,
171
relativeAngleL: leftAngle,
172
relativeAngleR: rightAngle,
173
absoluteSourceToCorner: newAbsolute,
174
cspf: _cspf)
175
{Tag = Tag + " Right"};
176
}
177
return new Tuple<Cone, Cone>(Left, Right);
178
}
179
180
private enum ShortestPathResult
181
{
182
Shortest,
183
NotShortest,
184
NotViable
185
}
186
187
private ShortestPathResult CheckIfShortestPath()
188
{
189
var originToSource = ML["- {0}"].Format(RelativeSource).Eval();
190
191
//TODO the cone might not be able to reach the endpoint, even if it reaches the facet.
192
if (AtEndFacet)
193
{
194
var relativeEndPoint = "{0}[{1}]".MsEvalWith(_anchorMatrix, _cspf.EndPoint.Expr);
195
var sourceToEnd = new EndPointPacket((new PointRef(RelativeSource)), new PointRef(relativeEndPoint));
196
if (_cspf.SeeIfConeHasShortestPath(this, sourceToEnd.Magnitude, _cspf.EndPoint))
197
{
198
var angleToEnd = SignedAngle(originToSource, sourceToEnd.AsVector);
199
TrueAngle = "{0} + {1}".MsEvalWith(_absoluteSourceToCorner, angleToEnd);
200
return ShortestPathResult.Shortest;
201
}
202
return ShortestPathResult.NotShortest;
203
}
204
return ShortestPathResult.NotViable;
205
}
206
207
private PointRef TransformOppositeVertex
208
{
209
get
210
{
211
return _workingHECopy.Next.End;
212
}
213
}
214
218
private Expr TransformSourceLeft
219
{
220
get
221
{
222
var lCopy = _currentCrossedHalfEdge.Prev.Opposite.FacetRingClone;
223
lCopy.Opposite = _workingHECopy.Prev;
224
lCopy.Unfold();
225
var transform = lCopy.AnchorMatrix;
226
return ML["{0}[{1}]"].Format(transform, RelativeSource).Eval();
227
}
228
}
229
233
private Expr TransformSourceRight
234
{
235
//TODO use AnchorMatrix instead perhaps
236
get
237
{
238
var rCopy = _currentCrossedHalfEdge.Next.Opposite.FacetRingClone;
239
rCopy.Opposite = _workingHECopy.Next;
240
rCopy.Unfold();
241
var transform = rCopy.AnchorMatrix;
242
243
return ML["{0}[{1}]"].Format(transform, RelativeSource).Eval();
244
}
245
}
246
247
public Expr TrueAngle { get; set; }
248
249
public ConvexShortestPathFinder Cspf
250
{
251
get { return _cspf; }
252
}
253
254
private Expr SignedAngle(Expr vector1, Expr vector2)
255
{
256
return VectorMath.SignedAngle(vector1, vector2);
257
}
258
259
public Expr ApproxAperture
260
{
261
get { return ML["N[Mod[({0} - {1}), 2*Pi]]"].Format(_relativeAngleL, _relativeAngleR).Eval(); }
262
}
263
264
public bool AtEndFacet
265
{
266
get { return _cspf.EndFacet.HalfEdges.Contains(_currentCrossedHalfEdge); }
267
}
268
269
public Expr ApproxLength
270
{
271
get
272
{
273
var mag = (new EndPointPacket(new PointRef(RelativeSource), PointRef.OriginRef)).Magnitude;
274
return ML["N"].Bracket(mag).Eval();
275
}
276
}
277
278
public Expr RelativeSource
279
{
280
get { return _relativeSource; }
281
}
282
}
283
284
public static class VectorMath
285
{
286
public static Expr SignedAngle(Expr vector1, Expr vector2)
287
{
288
return "Sign[Dot[{{ -{0}[[2]], {0}[[1]], 0 }}, {1}]]*ArcCos[Dot[Normalize[{0}], Normalize[{1}]]]"
289
.MsEvalWith(vector1, vector2);
290
}
291
}*/
292
}
DropBox
Dropbox
2013 REU
MathPolys
MathPolyLib
Cone2.cs
Generated on Thu Nov 21 2013 10:10:31 for PolyLink by
1.8.5