versor  3.0
C++11 library for Geometric algebra
vsr_knot.h
1 //
2 // vsr_knot.h
3 // Versor
4 /*
5  KNOTS -- building up from Dorst and Valkenburg's paper on Square Roots of Rotors and Logarithms through Polar Decomposition
6 
7 
8  IN PROGRESS!!!! Still owkring out the best way to do this (and what "this" is)
9 
10 */
11 // Created by Pablo Colapinto on 11/7/12.
12 // Copyright (c) 2012 __MyCompanyName__. All rights reserved.
13 //
14 
15 #ifndef Versor_vsr_knot_h
16 #define Versor_vsr_knot_h
17 
18 #include "vsr_fiber.h"
19 
20 namespace vsr { namespace cga {
21 
22 //A sort of Coupled Boost
23 
24 struct TorusKnot {
25 
26  //typically integers
27  double P, Q;
28 
29  //double cable;
30 
31  //A Circle base with methods for finding the links around which to knot . . .
32  HopfFiber HF;
33 
35  vector<Cir> cir;
37  vector<Pnt> pnt;
38 
39  vector<double> energies;
40 
41  void clear(){
42  cir.clear();
43  pnt.clear();
44  energies.clear();
45  }
46 
47  double amt; //RES default
48 
49  TorusKnot& add(const Pnt& p){
50  pnt.push_back(p); return *this;
51  }
52 
53  TorusKnot& add(const Cir& c){
54  cir.push_back(c); return *this;
55  }
56 // int num() { return pnt.size(); }
57  int iter() {
58  return ( P == 0 || Q == 0 ) ? 1.0/amt : P * Q / (amt * Round::size(HF.cir(), false) );
59  }
60 
61  Par par() {
62  double a = P == 0 ? 0 : PI/P; double b = Q == 0 ? 0 : PI/Q;
63  return HF.fiberA().dual() * a + HF.fiberB().dual() * b;
64  }
65 
66  Bst bst() {
67  return Gen::bst( par() * amt );
68  }
69 
70  Bst bst(double t) { amt = t; return bst(); }
71 
72  TorusKnot(double p = 3, double q = 2, double a = .01) : P(p), Q(q), amt(a) {}
73 
74  //Calculate full orbit from point p
75  void calc( const Pnt& p){
76  pnt.clear(); cir.clear();
77 
78  Pnt np = p;
79  Bst tbst = bst();
80  int tnum = iter();
81 
82  for (int i = 0; i < tnum; ++ i ){
83  np = Round::loc( np.sp( tbst ) );
84  add(np);
85  }
86 
87  //Tube Neighborhood
88  for (int i = 0; i < tnum; ++i ){
89  //double t = -1 + 2.0 * i/ tnum;
90  //double tt = 1 + t * t;
91  int idx = i < tnum -1 ? i + 1 : 0;
92  Par tpar = pnt[i] ^ pnt[idx];
93  Cir c = tpar.dual();//.dil(tk.pnt[i], );
94  add ( c );
95  }
96  }
97 
98  //calculate full orbit from point p without renormalizing at each step (no tube)
99  void calc0( const Pnt& p){
100  pnt.clear(); cir.clear();
101  Pnt np = p;
102  Bst tbst = bst();
103  int tnum = iter();
104 
105  for (int i = 0; i < tnum; ++ i ){
106  np = np.sp( tbst ) ;
107  add( Round::loc( np) );
108  }
109 
110  //Tube Neighborhood
111  for (int i = 0; i < tnum; ++i ){
112  //double t = -1 + 2.0 * i/ tnum;
113  //double tt = 1 + t * t;
114  int idx = i < tnum -1 ? i + 1 : 0;
115  Par tpar = pnt[i] ^ pnt[idx];
116  Cir c = tpar.dual();//.dil(tk.pnt[i], );
117  add ( c );
118  }
119 
120  }
121 
122  template<typename T>
123  vector<T> apply0(const T& input){
124  vector<T> output;
125  auto tbst = bst();
126  auto tmp = input;
127  for (int i=0; i<iter();++i){
128  tmp = tmp.spin(tbst);
129  output.push_back( Round::loc(tmp) );
130  }
131  return output;
132  }
133 
134  double energy(int idx, int num){
135 
136  double totalEnergy = 0;
137  energies.clear();
138  energies.push_back(0);
139 
140  //forward and reverse arc measurements
141  vector<double> globalA; //Distance
142  //vector<double> globalB;
143  vector<double> local; //Distance
144 
145  double totalA = 0;
146 
147  //integrated sums
148  for (int i = 0; i < num; ++i){
149 
150  //Idx of Neighbor
151  int idxA = i < num - 1 ? i + 1 : 0;
152 
153  double ta = Round::dist( pnt[i], pnt[idxA]);
154  local.push_back(ta);
155 
156  totalA += ta;
157 
158  globalA.push_back( totalA );
159  }
160 
161  for (int i = 0; i < num; ++i){
162 
163  double ta = 0;
164 
165  for (int j = 0; j < num; ++j){
166 
167  if ( i != j ) {
168  double chord = Round::sqd( pnt[i], pnt[j] );
169 
170  double diffA = fabs( globalA[j] - globalA[i] );
171  double diffB = fabs( (totalA - globalA[j] ) + globalA[i] );//fabs( globalB[j] - globalA[i] );
172 
173  double diff = diffA < diffB ? diffA : diffB;
174 
175  double tener = ( ( 1.0 / chord ) - (1.0 / (diff * diff) ) ) * local[j]; //weighted by distance
176  //push back for i = 0
177  if (i == idx ) energies.push_back(tener);
178  ta += tener;
179  }
180  }
181 
182  totalEnergy += ta * local[i];
183  }
184 
185  return totalEnergy;
186  }
187 
188 
189 
190 };
191 
192 
193 // /*! Generates an Orbit around a Real, Imaginary, or Null Point Pair */
194 // class Orbit : public Frame {
195 // Frame sF, mF;
196 // double mM, mAmt;
197 // bool bReal, bNull;
198 // public:
199 //
200 //
201 //
202 // Orbit() : Frame(), sF(PT(0,0,0)), mM(1), mAmt(.01), bReal(false), bNull(false)
203 // { calc(); }
204 //
205 // Orbit( const Frame& f): Frame(f), sF(PT(0,0,0)), mM(1), mAmt(.01), bReal(false), bNull(false)
206 // { calc(); }
207 //
208 // bool& real() { return bReal; }
209 // bool& null() { return bNull; }
210 // double& m() { return mM; }
211 // double& amt() { return mAmt; }
212 //
213 // Frame& sf() { return sF; }
214 // Frame& mf() { return mF; }
215 //
216 //
217 // bool real() const { return bReal; }
218 // bool null() const { return bNull; }
219 // double m() const { return mM; }
220 // double amt() const { return mAmt; }
221 //
222 // Frame sf() const { return sF; }
223 // Frame f() const { return mF; }
224 //
225 // Par par() const { return ( ( bNull ) ? mF.tx() : mF.px(bReal) ) * PI/mM ; }
226 // Cir cir() const { return mF.px(bReal).undual(); }
227 //
228 // void calc() {
229 // mF = sF;
230 // mF.mot( sF.mot() * mot() );
231 // }
232 //
233 // Bst bst() { return Gen::bst( par() * mAmt ); }
234 //
235 // Par par(const Orbit& o, double t){
236 // Orbit no = Frame::Twist( f(), o.f(), t );
237 //
238 // return no.par();
239 // //return par() * (1-t) + o.par() * t;
240 // }
241 //
242 //
243 // };
244 
245 // class Knot : public Frame {
246 //
247 // Frame sFa, sFb;
248 // Frame mFa, mFb;
249 //
250 // Par mPar;
251 //
252 // double mM, mN;
253 // double mAmt, mDense;
254 // double mDist;
255 //
256 // bool bRealA, bRealB, bNullA, bNullB;
257 //
258 // public:
259 //
260 // Knot() : Frame(),
261 // mAmt(.01), mDense(1.0), mM(2), mN(2),
262 // sFa( PT(0,-.5,0) ), sFb( PT(0,.5,0) ),
263 // bRealA(false), bRealB(false), bNullA(false), bNullB(false)
264 // { cout << mFa.scale() << endl; calc(); }
265 //
266 // double& dist() { return mDist; }
267 // double dist() const { return mDist; }
268 // double& amt() { return mAmt; }
269 // double amt() const { return mAmt; }
270 // double& m() { return mM; }
271 // double& n() { return mN; }
272 // double m() const { return mM; }
273 // double n() const { return mN; }
274 //
275 // bool& ra() { return bRealA; }
276 // bool& rb() { return bRealB; }
277 // bool ra() const { return bRealA; }
278 // bool rb() const { return bRealB; }
279 // bool& ba() { return bNullA; }
280 // bool& bb() { return bNullB; }
281 // bool ba() const { return bNullA; }
282 // bool bb() const { return bNullB; }
283 //
284 // Frame& sfa() { return sFa; }
285 // Frame& sfb() { return sFb; }
286 // Frame sfa() const { return sFa; }
287 // Frame sfb() const { return sFb; }
288 // Frame& fa() { return mFa; }
289 // Frame& fb() { return mFb; }
290 // Frame fa() const { return mFa; }
291 // Frame fb() const { return mFb; }
292 //
293 // Par pa(bool real = false) const { return bNullA ? mFa.tx() : mFa.px(real); }
294 // Par pb(bool real = false ) const { return bNullB ? mFb.tz() : mFb.pz(real); }
295 //
296 // Cir ca(bool real = false) const { return mFa.px(real).undual(); }
297 // Cir cb(bool real = false ) const { return mFb.pz(real).undual();}
298 //
299 // int num() { return mM * mN / mAmt; }
300 //
301 // void calc() {
302 // sFa.pos() = PT(0,-mDist/2.0,0);
303 // sFb.pos() = PT(0,mDist/2.0,0);
304 //
305 // Mot ma = sFa.mot() * mot();
306 // Mot mb = sFb.mot() * mot();
307 // mFa.mot( ma ); mFb.mot( mb );
308 // mPar = pa(bRealA) * ( mM == 0 ? 0 :PI/mM ) + pb(bRealB) * ( mN == 0 ? 0 :PI/mN );
309 // }
310 //
311 // Par par() const { return mPar; }
312 // Par& par() { return mPar; }
313 //
314 // Par para() const { return pa(bRealA) * PI/mM; }
315 // Par parb() const { return pb(bRealB) * PI/mN; }
316 //
317 // //Separated out
318 // Bst bsta() const { return Gen::bst( para() * mAmt ); }
319 // Bst bstb() const { return Gen::bst( parb() * mAmt ); }
320 // Bst bstc() const { return bsta() * bstb(); }
321 //
322 // Bst bst() { return Gen::bst( par() * mAmt ); }
323 //
324 // //? not sure what this would do or should do
325 // Knot operator * (const Knot& k){
326 //
327 // }
328 //
329 // static Bst bst(const Knot& ka, const Knot& kb, double t){
330 // return Gen::bst( ka.par() * (1-t) + kb.par() * t );
331 // }
332 //
333 //
334 // template<class T>
335 // T operator () (const T& t) { return t.sp( bst() ); }
336 //
337 //
338 // };
339 
340 } }//vsr::cga
341 
342 #endif
static Bst bst(const Pair &p)
vsr::cga::Boost from vsr::cga::Pair
NCir< 5 > Cir
Circle
Definition: vsr_cga3D_types.h:74
Generic Geometric Number Types (templated on an algebra and a basis )
Definition: vsr_algebra.h:69
vector< double > energies
Energy at idx (from pnt 0)
Definition: vsr_knot.h:39
static VSR_PRECISION sqd(const Point &a, const Point b)
Squared distance between two points.
Definition: vsr_cga3D_round.h:233
static Point loc(const A &s)
Location (normalizd) of a Round Element (shorthand)
Definition: vsr_cga3D_round.h:146
NPar< 5 > Par
Pair
Definition: vsr_cga3D_types.h:73
NBst< 5 > Bst
Boost
Definition: vsr_cga3D_types.h:94
Hopf Fibration
Definition: vsr_fiber.h:26
vector< Pnt > pnt
A vector of points in the knot orbit.
Definition: vsr_knot.h:37
vector< Cir > cir
A vector of circles in the knot orbit.
Definition: vsr_knot.h:35
Definition: vsr_knot.h:24
double energy(int idx, int num)
Definition: vsr_knot.h:134
static VSR_PRECISION dist(const Point &a, const Point &b)
Distance between points a and b (shorthand)
Definition: vsr_cga3D_round.h:239
the versor library namespace
Definition: vsr_algebra.h:29
static VSR_PRECISION size(const DualSphere &s, bool bDual=true)
Squared Size of a DualSphere (result could be negative)
NPnt< 5 > Pnt
Point
Definition: vsr_cga3D_types.h:72