-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathREADME.html
727 lines (569 loc) · 32.8 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<link type="text/css" rel="stylesheet" href="style0.css"/>
</head>
<body>
<script type="text/javascript"
src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<p><img src = "resources/images/cshape.gif" width = 80>
<img src = "resources/images/twine_0.gif" width = 100>
<img src = "resources/images/twist_04_bw.gif" width = 400>
<img src = "resources/images/lox_0.jpg" width = 100></p>
<h1 id="versorlibvsrversion1.0">Versor (libvsr) Version 1.0</h1>
<h2 id="afastclibraryforconformalgeometricalgebra.">A (Fast) C++ library for Conformal Geometric Algebra.</h2>
<h3 id="currentlytestedonlinuxandmacosx">Currently tested on Linux and Mac OS X</h3>
<p>Developer: Pablo Colapinto<br/>
<code>gmail: wolftype</code> </p>
<p><a href="http://versor.mat.ucsb.edu">Homepage (versor.mat.ucsb.edu)</a></p>
<p><a href="http://versor.mat.ucsb.edu/INSTALL.html">Download and Installation Instructions</a> </p>
<p><a href="http://github.com/weshoke/versor.js">A Javascript Port of Versor</a> </p>
<p><a href="http://versor.mat.ucsb.edu/masters_appendix.pdf">Reference Guide to the Elements</a></p>
<p><a href="http://lists.create.ucsb.edu/mailman/listinfo/versor">Join the Mailing List (for update notifications, to ask questions, discuss bugs, etc)</a> </p>
<p><a href="http://wolftype.com/versor/colapinto_masters_final_02.pdf">Read my Master’s Thesis on the Subject</a></p>
<p><a href="#papers">Other links, Resources, Papers</a></p>
<p><a href="http://www.allosphere.ucsb.edu/">Look at the AlloSphere Research Group</a> </p>
<pre><code>As long as algebra and geometry have been separated, their progress have been slow and their uses limited; but when these two sciences have been united, they have lent each mutual forces, and have marched together towards perfection.
-Joseph Louis Lagrange
No attention should be paid to the fact that algebra and geometry are different in appearance.
-Omar Khayyám
L’algèbre n’est qu’une géométrie écrite; la géométrie n’est qu’une algèbre figurée.
-Sophie Germain
If you want to see, learn how to act
-Heinz von Foerster
</code></pre>
<h2 id="contents:">CONTENTS:</h2>
<ul>
<li><a href="#introduction">INTRODUCTION</a></li>
<li><a href="#whathepointis">WHAT THE POINT IS</a></li>
<li><a href="#speed">SPEED</a></li>
<li><a href="#basics">BASICS</a></li>
<li><a href="#methods">METHODS</a></li>
<li><a href="#generators">GENERATORS</a></li>
<li><a href="#gui">GUI</a></li>
<li><a href="#operators">OPERATORS</a></li>
<li><a href="#elements">ELEMENTS</a></li>
<li><a href="#links">LINKS</a></li>
</ul>
<h2 id="othernicesoftware:">OTHER NICE SOFTWARE:</h2>
<ul>
<li><a href="http://www.cinderella.de/tiki-index.php">Cinderella</a> Standalone GA interface</li>
<li><a href="http://www.science.uva.nl/ga/viewer/content_viewer.html">GAViewer</a> Standalone GA interface</li>
<li><a href="http://staff.science.uva.nl/~fontijne/g25.html">Gaigen</a> An Implementation Generator</li>
<li><a href="http://www.clucalc.info/">CluCalc/CluViz</a> Standalone and Library</li>
<li><a href="http://github.com/weshoke/versor.js">versor.js</a> A javascript port of this library</li>
</ul>
<hr />
<ol>
<li><strong>To INSTALL please read the <a href="http://versor.mat.ucsb.edu/INSTALL.html">INSTALL file</a></strong></li>
<li><strong>The current document is a work-in-progress! For specific questions please do not hesitate to contact me: wolftype (at) gmail dot com</strong></li>
</ol>
<hr />
<h2 id="introduction">INTRODUCTION</h2>
<p>This package provides operations and draw routines for conformal geometric algebra,
a relatively new spatial computing model used by physicists, engineers, and artists. <em>Versor</em> is designed to make graphical
experimentation of conformal geometric algebra within a C++ environment easier.
You can use this library to draw geometrical things, explore spherical and hyperbolic spaces, transformations, design robots, etc.
I am using it for my PhD on bio-inspired engineering.</p>
<p>I first developed <em>Versor</em> while reading “Geometric Algebra for Computer Science” by Leo Dorst, Daniel Fontijne, and Stephen Mann.
It’s a fantastic book and if you’re reading this you should also consider reading that. </p>
<p>Built to aid in my modelling of organic forms, the initial development was funded in large part by the Olivia Long Converse Fellowship for Botanic research,
courtesy of the Graduate Division at the University of California in Santa Barbara. So this software is under a UC Regents General Public License.</p>
<p>See also the <a href="#links">links</a> below for more information, including some videos.
The Doc folder has a doxygen which I periodically tidy up. Lots of test files too.</p>
<p>A full-fledged tutorial is in the works … but a basic intro follows </p>
<hr />
<p>One quick word: clifford algebras and the spatial relationships they embody can often feel abstract and daunting. But it’s a twisty, boosty ride, full of weird discoveries. You’re bound to make some, so have fun!</p>
<hr />
<h4 id="background">BACKGROUND</h4>
<p>The homogenous 5D CGA model used here was initially proposed by David Hestenes, Hongbo Li, and Alan Rockwood in 2001, and given full form and weight through the excellent
and careful work of Leo Dorst, Joan and Anthony Lasenby, and Eduardo Bayro-Corrochano, and others. These researchers’ writings have helped me quite a bit. CGA is particular breed of <em>Clifford Algebras</em> (also known as Geometric Algebras),
which operate upon combinatoric hypercomplex vector spaces that emerged from William Clifford’s attempt to fuse Hamilton’s quaternions with Grassmans’ extension algebras. Thus
<em>transformations</em> were married with a system of <em>abstraction</em>. For more information, take a look at the <a href="#links">links</a> to the sites at the bottom of
this page. For instance, for practical applications in robotics and “Geometric Cybernetics”, see Eduardo Bayro-Corrochano’s work. For some
very helpful algorithms in rigid body dynamics and gravitational physics see the variety of publications by Joan and Anthony Lasenby. To get at the beginning of it all, read David Hestenes’ <em>New Foundations for Classical Mechanics</em>. </p>
<h4 id="license">LICENSE</h4>
<p>This software is licensed under a general UC Regents General Public License. If you’re planning on using CGA inside a sellable product you should be aware that
there is a vague patent on the use of 5D CGA which <em>may</em> limit its <em>commercial</em> use when encoding robotic control mechanisms, or may just limit your ability to patent
the model itself. I hope and imagine it is the latter. Though powerful, elegant, and brilliant, the heart of CGA is just a quadratic equation and the arguments for
the use of 5D CGA are that it is <em>foundational</em> and <em>universal</em>, the very two characteristics of a system which would make it un-patentable. The Clifford Algebras on which it is based are from the 19th century.</p>
<h4 id="speed">SPEED</h4>
<p>Typical matrix operation libraries have templated inlined functions for Vector and Matrix multiplication. Versor
is similar, but on steroids, where <em>vectors</em> and sparse <em>matrices</em> of various sizes are all just called <em>multivectors</em> and represent geometric
elements beyond just xyz directions and transformation matrices. Circles, lines, spheres, planes, points are all algebraic elements, as are
operators that spin, twist, dilate, and bend those variables. Both these elements and operators are <em>multivectors</em> which multiply together in many many many different ways. </p>
<p>The backbone of Versor’s library is a precomputation table of the most likely (though <em>not all</em>) multiplications you could possibly hope to use.<br/>
It is a highly templatized and inlined extravaganza of function calls. Of course, there are also many useful algorithms included for manipulating geometric elements.
Most of these useful algorithms are located in the<code>vsr_op.h</code> file.</p>
<p>A Circle, for instance, can be <em>outer</em>-multiplied by a Plane to get the Point Pair where they intersect. </p>
<p>The current version of Versor is built for operational speed, with the expense of slightly longer compile times.<br/>
The makefile builds the STATIC version of this library, which currently gives up a bit of abstraction
(no inherited generic Multivector class) in exchange for a 5x speed boost (and 10x decrease in file size).</p>
<p>Future versions will likely use jit compilation to take care of this (i.e. combine speed with lightweight implementation), by hooking into
luajit for instance. I am working on that with Graham Wakefield and his thoughtful guidance and tutelage. Additionally, there is a trade off I am working on where you have an MVBase class with which you can make arbitrary functions. This requires a bunch of pointer being copied and has led to code bloat. GA is a tricky world of unknown return types.<br/>
The C++11 standards should help (for instance, “auto” return types), but are not implemented here. </p>
<h2 id="whatthepointis">WHAT THE POINT IS</h2>
<p>GA combines many other maths (matrix, tensor, vector, and lie algebras). It is <strong>holistic</strong>. CGA uses a particular mapping (a conformal one) of 3D Euclidean space to a
4D sphere. Operations on that hypersphere are then projected back down to 3D. That how it works in a nutshell. </p>
<p>A fuller treatment of this question (er, the question of why we do this) can be found in my <a href="http://wolftype.com/versor/colapinto_masters_final_02.pdf">Master’s thesis on the subject</a>. But basically,
Geometic Algebra offers a particular richness of spatial expression. Imagine needing glasses and not knowing you needed glasses. Then, when you do get glasses, the world changes
unexpectedly. GA is like glasses for the inside of your brain. <em>Conformal</em> Geometric Algebra, especially the 5D variety enlisted here, are like x-ray glasses. One
point of clarification that occurs are <strong>disambiguations</strong> of previously collapsed concepts. </p>
<p>For instance, the main disambiguation, is that between a <em>Point</em> in space and a <em>Vector</em> in space.<br/>
A Point has no magnitude, but a Vector does. A Point has no direction, but a Vector does. Points are <em>null</em> Vectors. We can make them
by writing</p>
<pre><code>Vec( 1,0,0 ).null();
</code></pre>
<ul>
<li>Points are null Vectors</li>
<li>Points square to 0</li>
<li>The dot (inner) product of two Points returns their squared distance</li>
<li>The wedge (outer) product of two Points returns a Point Pair</li>
</ul>
<p>More on that last point later … there are various binary operators defined (mainly three). We can introduce one right now, which is the <strong>dot</strong> or <strong>inner</strong> product.
In mathematics, the inner product of two points <code>pa</code> and <code>pb</code> is written <span class="math">\(p_{a} \rfloor p_{b}\)</span>. In <em>Versor</em> we use the <code><=</code> operator:</p>
<pre><code>Point pa = Vec(1,0,0).null();
Point pb = Vec(-1,0,0).null();
Scalar squaredDist = ( pa <= pb ) * -2;
</code></pre>
<p>which in this case would return a Scalar value of <code>4</code>. The <code>-2</code> is there since the inner product really returns <strong>half the negative</strong> squared distance.
We can extract the Scalar into a c++ double like so:</p>
<pre><code>double squaredDist = ( pa <= pb )[0] * -2;
</code></pre>
<p>Points thought of as Spheres (really, Dual Spheres, more on <em>Duality</em> later): they are Spheres of zero radius. As such they are a type of <em>Round</em> element. We can also build points this way:</p>
<pre><code>Round::null( 1,0,0 );
</code></pre>
<p>or you can pass in another element</p>
<pre><code>Round::null( Vec(1,0,0) );
</code></pre>
<p>or use the built-in method</p>
<pre><code>Point pa = Vec(1,0,0).null();
</code></pre>
<p>Points can also be made with the macro <code>PT</code></p>
<pre><code>Point pa = PT(1,0,0);
</code></pre>
<p>which is just “syntactic sugar” for <code>Vec(1,0,0).null()</code></p>
<p>Speaking of Spheres, we can also make spheres with a radius this way:</p>
<pre><code>DualSphere dls = Round::dls( Vec( 1,0,0 ).null(), 1 );
</code></pre>
<p>or </p>
<pre><code>DualSphere dls = Round::dls( Vec( 1,0,0 ), 1 );
</code></pre>
<p>or </p>
<pre><code>DualSphere dls = Round::dls( 1,0,0,1 )
</code></pre>
<p>all of which give a dual sphere of radius 1 at coordinate 1,0,0; </p>
<h2 id="basics">BASICS</h2>
<p><em>Versor</em> is named after the one of the basic category of elements of geometric algebra.<br/>
A <strong>versor</strong> is a type of <strong>multivector</strong> which can be used to compose geometric transformations,
namely reflections, translations, rotations, twists, dilations, and transversions (special conformal transformations).</p>
<p>More on all of those transformations later. </p>
<p>In Versor, a <code>Vector</code> (or <code>Vec</code>) is a typical Euclidean 3D element. It can be built in the normal way:</p>
<pre><code>Vec v(1,2,3);
</code></pre>
<p>Some built-in Vectors exist:</p>
<pre><code>Vec::x x; //<-- X Direction Unit Vector Vec(1,0,0)
Vec::y y; //<-- Y Direction Unit Vector Vec(0,1,0)
Vec::z z; //<-- Z Direction Unit Vector Vec(0,0,1)
</code></pre>
<p>A <code>Vector</code> can be spun around using a <code>Rotor</code>, which is exactly like a quaternion. However, whereas quaternions are often built by specifying an axis
and an angle, rotors are built by specifying the <strong>plane</strong> of rotation. Eventually this will make much more sense to you: in general <strong>planes</strong> are what we
will be using to transform things. For instance, a reflection is a reflection in a plane. As we will see, planes can become <strong>hyperplanes</strong> which will allow for more extraordinary transformations.</p>
<p>The first completely new element to introduce is the <code>Bivector</code>, which is the plane we will use to generate our <code>Rotor</code>. Bivectors represent <strong>directed areas</strong> and are <strong>dual</strong>
to the cross product: the cross product of two vectors in typical vector algebra returns a vector normal to the plane they define. So it is not completely new,
but just sort of new.</p>
<p>Bivectors are also just three elements long, and are built the same way Vectors are.</p>
<pre><code>Biv b(1,2,3);
</code></pre>
<p>Some built-in Bivectors exist:</p>
<pre><code>Biv::xy xy; //<-- XY Counterclockwise Unit Area Biv(1,0,0)
Biv::xz xy; //<-- XZ Counterclockwise Unit Area Biv(0,1,0)
Biv::yz xy; //<-- YZ Counterclockwise Unit Area Biv(0,0,1)
</code></pre>
<p>While it is perfectly valid to write <code>Vector</code>, <code>Bivector</code> and <code>Rotor</code>, you’ll notice I’ve truncated them to their three letter nicknames, <code>Vec</code> and <code>Rot</code>.<br/>
That’s up to you: Both long-name and nick-name versions are valid in libvsr (they are typedef’ed to each other).</p>
<pre><code>Biv b = Biv::xy;
double theta = PIOVERTWO;
Vec v1 = Vec::x.rot( b * theta )
</code></pre>
<p>You can also generate rotors using <code>Gen::rot( <some bivector> )</code> In fact, all transformations can be generated this way, and then later applied to arbitrary elements.
For instance, <code>Motors</code> can be generated which translate and rotate an element at the same time. This is also called a <em>twist</em>.</p>
<pre><code>Motor m = Gen::mot(<some dual line>); //<-- Makes A Twisting Motor around Some Dual Line
Point p = Vec(0,0,0).null().sp(m); //<-- Applies above motor to a Point
</code></pre>
<p>You’ll notice there are <em>dual</em> versions of elements: as in a <code>DualLine</code> (or <code>Dll</code> for short). That’s because in the real world of abstract geometry, there are usually
two ways of defining an element. For instance, we can build a <em>direct</em> <code>Line</code> on the Y-axis by wedging two points together, along with infinity:</p>
<pre><code>Line lin = Vec(0,0,0).null() ^ Vec(0,1,0).null() ^ Inf(1);
</code></pre>
<p>Or we can define a line by the bivector plane that it is normal to, and a support vector that determines how far away the line is from the origin. To convert the above
line into its dual representation, we just call the dual() method:</p>
<pre><code>Dll dll = lin.dual();
</code></pre>
<p>For those who are interested, this dual representation is isomorphic to the Plücker coordinates, which are used in screw theory to twist things around. Here, too, we can use
dual lines to generate transformations which twist things around them. </p>
<h2 id="methods">METHODS</h2>
<p><code>vsr_op.h</code> contains the bulk of the functions for generating elements from other elements. Some guidelines:</p>
<ul>
<li><code>Generate::</code> or <code>Gen::</code> methods generate or otherwise operate on versors</li>
<li><code>Round::</code> or <code>Ro::</code> methods create or otherwise operate on Round elements (Points, Point Pairs, Circles, Spheres)</li>
<li><code>Flat::</code> or <code>Fl::</code> methods create or otherwise operate on Flat elements (Lines, Dual Lines, Planes, Dual Planes, or Flat Points)</li>
</ul>
<p>You notice I’ve been throwing around the <code>null()</code> method a lot, </p>
<h2 id="generators">GENERATORS</h2>
<pre><code>Rotor Gen::rot( const Biv& b ); //<-- Generate a Rotor from a Bivector
Translator Gen::trs( const Drv& v); //<-- Generate a Translator from a Direction Vector
Motor Gen::mot( const Dll& d); //<-- Generate a Motor from a Dual Line
Dilator Gen::dil( const Pnt& p, double amt ); //<-- Generate a Dilator from a Point and an amount
Transversor Gen::trv( cont Tnv& v); //<-- Generate a Transveror from a Tangent Vector
Booster Gen::bst( const Par& p); //<-- Generate a Booster from a Point Pair
</code></pre>
<h2 id="gui">GUI</h2>
<p>The TestExamples include bindings to the GLV framework for windowing and user interface controls. A GLVApp class and GLVInterface class provide the necessary glue.</p>
<p>The interface has a built in gui, mouse info, and keyboard info stored. </p>
<pre><code>static Circle circle;
interface.touch(circle);
DRAW(circle);
</code></pre>
<p>Putting the above code inside your application’s <code>onDraw()</code> loop will enable you to click and modify geometric elements by hitting the “G”, “R” and “S” keys. Hit “Q” to deselect all elements. </p>
<table>
<caption id="built-ininterface"><strong>BUILT-IN INTERFACE</strong></caption>
<colgroup>
<col style="text-align:left;"/>
<col style="text-align:left;"/>
</colgroup>
<thead>
<tr>
<th style="text-align:left;"></th>
<th style="text-align:left;"></th>
</tr>
<tr>
<th style="text-align:left;">Key</th>
<th style="text-align:left;">Response</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;"><code>~</code></td>
<td style="text-align:left;">Toggle full screen.</td>
</tr>
<tr>
<td style="text-align:left;"><code>SHIFT</code> + <code>Arrow Keys</code></td>
<td style="text-align:left;">navigates the camera in x and z directions.</td>
</tr>
<tr>
<td style="text-align:left;"><code>SHIFT</code>+<code>CONTROL</code>+<code>Arrow Keys</code></td>
<td style="text-align:left;">navigates the camera in Y direction</td>
</tr>
<tr>
<td style="text-align:left;"><code>OPTION</code> +<code>Arrow Keys</code></td>
<td style="text-align:left;">spins the model view around.</td>
</tr>
<tr>
<td style="text-align:left;"><code>G</code></td>
<td style="text-align:left;">Grab an Element</td>
</tr>
<tr>
<td style="text-align:left;"><code>R</code></td>
<td style="text-align:left;">Rotate an Element</td>
</tr>
<tr>
<td style="text-align:left;"><code>S</code></td>
<td style="text-align:left;">Scale an Element</td>
</tr>
<tr>
<td style="text-align:left;"><code>V</code></td>
<td style="text-align:left;">Print out still (to postscript) </td>
</tr>
</tbody>
</table>
<h2 id="operators">OPERATORS</h2>
<p>The elements of the algebra are geometric entities (circles, planes, spheres, etc) and operators (rotations, translations, twists, etc) which
act on the elements of the algebra. All are known as <em>multivectors</em> since they are more than just your typical vectors.</p>
<p>Multivector elements are most often combined using three overloaded binary operators: </p>
<p>The <strong>Geometric</strong> Product of elements <code>A</code> and <code>B</code>: </p>
<pre><code>A * B
</code></pre>
<p>multiplies two multivector elements together. This is most useful when multiplying one by the inverse of another (see <code>!</code> operator, below).</p>
<p>The <strong>Outer</strong> Product of elements <code>A</code> and <code>B</code>: </p>
<pre><code>A ^ B
</code></pre>
<p>“wedges” two multivectors together. Its from Grassman’s algebra of extensions, and can be thought of as a way of creating higher dimensions from smaller ones.
For instance, wedging two <code>Vectors</code> (directed magnitudes) together returns a <code>Bivector</code> (a directed Area). Wedging two <code>Points</code> together returns a <code>PointPair</code>.
Wedging three <code>Points</code> together returns a <code>Circle</code>.</p>
<p>The <strong>Inner</strong> Product of elements <code>A</code> and <code>B</code>:</p>
<pre><code>A<=B
</code></pre>
<p>There is also a <strong>Commutator</strong> product (differential)</p>
<pre><code>A%B
</code></pre>
<p>And a few overloaded operations, including,</p>
<p>The Inverse: </p>
<pre><code>!A
</code></pre>
<p>returns <span class="math">\(A^{-1}\)</span></p>
<p>The Reverse: </p>
<pre><code>~A
</code></pre>
<p>returns <span class="math">\(\tilde{A}\)</span></p>
<p>And finally, since I ran out of overloadable operators, some basic methods</p>
<pre><code>A.conjugation()
</code></pre>
<p>which returns <span class="math">\(\bar{A}\)</span></p>
<pre><code>A.involution()
</code></pre>
<p>which returns <span class="math">\(\hat{A}\)</span></p>
<p>In summary: </p>
<table>
<colgroup>
<col style="text-align:left;"/>
<col style="text-align:left;"/>
<col style="text-align:center;"/>
<col style="text-align:left;"/>
</colgroup>
<thead>
<tr>
<th style="text-align:left;">Versor</th>
<th style="text-align:left;">Math</th>
<th style="text-align:center;">Description</th>
<th style="text-align:left;"></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;"><code>A * B</code></td>
<td style="text-align:left;"><span class="math">\(AB\)</span></td>
<td style="text-align:center;">Multiplies two elements together (and, in the case of A * !B finds ratios between elements).</td>
</tr>
<tr>
<td style="text-align:left;"><code>A ^ B</code></td>
<td style="text-align:left;"><span class="math">\(A \wedge B\)</span></td>
<td style="text-align:center;">Wedges two elements together (builds up higher dimensional elements).</td>
</tr>
<tr>
<td style="text-align:left;"><code>A <= B</code></td>
<td style="text-align:left;"><span class="math">\(A \rfloor B\)</span> or <span class="math">\(\boldsymbol{a} \cdot B\)</span></td>
<td style="text-align:center;">Contracts A out of B (returns the part of B “least like A”, sort of).</td>
</tr>
<tr>
<td style="text-align:left;"><code>A % B</code></td>
<td style="text-align:left;"><span class="math">\(A \times B\)</span></td>
<td style="text-align:center;">Commutator, equal to <span class="math">\(\frac{1}{2}(AB-BA)\)</span></td>
</tr>
<tr>
<td style="text-align:left;"><code>!A</code></td>
<td style="text-align:left;"><span class="math">\(A^{-1}\)</span></td>
<td style="text-align:center;">The Inverse of A.</td>
</tr>
<tr>
<td style="text-align:left;"><code>~A</code></td>
<td style="text-align:left;"><span class="math">\(\tilde{A}\)</span></td>
<td style="text-align:center;">The Reverse of A.</td>
</tr>
<tr>
<td style="text-align:left;"><code>A.conjugation()</code></td>
<td style="text-align:left;"><span class="math">\(\bar{A}\)</span></td>
<td style="text-align:center;">Conjugation.</td>
</tr>
<tr>
<td style="text-align:left;"><code>A.involution()</code></td>
<td style="text-align:left;"><span class="math">\(\hat{A}\)</span></td>
<td style="text-align:center;">Involution. </td>
</tr>
</tbody>
</table>
<h2 id="elements">ELEMENTS</h2>
<p>To make the process of writing code faster, all elements of the algebra are represented by types 3 letters long.
Alternatively, you can also use the long-form name.</p>
<table>
<caption id="basicelements"><strong>BASIC ELEMENTS</strong></caption>
<colgroup>
<col style="text-align:left;"/>
<col style="text-align:left;"/>
<col style="text-align:center;"/>
</colgroup>
<thead>
<tr>
<th style="text-align:left;">Type</th>
<th style="text-align:left;"></th>
<th style="text-align:center;"></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;" colspan="2"><em>Euclidean</em></td>
</tr>
<tr>
<td style="text-align:left;"><code>Sca</code></td>
<td style="text-align:left;"><code>Scalar</code></td>
<td style="text-align:center;">A real number</td>
</tr>
<tr>
<td style="text-align:left;"><code>Vec</code></td>
<td style="text-align:left;"><code>Vector</code></td>
<td style="text-align:center;">A Directed Magnitude, or 3D Vector, typical cartesian stuff</td>
</tr>
<tr>
<td style="text-align:left;"><code>Biv</code></td>
<td style="text-align:left;"><code>Bivector</code></td>
<td style="text-align:center;">A Directed Area. Use them to make Rotors: <code>Gen::Rot( Biv b )</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Tri</code></td>
<td style="text-align:left;"><code>Trivector</code></td>
<td style="text-align:center;">A Directed Volume Element </td>
</tr>
</tbody>
<tbody>
<tr>
<td style="text-align:left;" colspan="2"><em>Round</em></td>
</tr>
<tr>
<td style="text-align:left;"><code>Pnt</code></td>
<td style="text-align:left;"><code>Point</code></td>
<td style="text-align:center;">A Null Vector: <code>Pnt a = Vec(1,0,0).null()</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Par</code></td>
<td style="text-align:left;"><code>PointPair</code></td>
<td style="text-align:center;">A 0-Sphere (Sphere on a Line): <code>Par par = Pnt a ^ Pnt b</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Cir</code></td>
<td style="text-align:left;"><code>Circle</code></td>
<td style="text-align:center;">A 1-Sphere: <code>Cir cir = Pnt a ^ Pnt b ^ Pnt c</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Sph</code></td>
<td style="text-align:left;"><code>Sphere</code></td>
<td style="text-align:center;">A 2-Sphere: <code>Sph sph = Pnt a ^ Pnt b ^ Pnt c ^ Pnt d</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Dls</code></td>
<td style="text-align:left;"><code>DualSphere</code></td>
<td style="text-align:center;">Typedef’ed as a point: <code>typedef Pnt Dls</code> </td>
</tr>
</tbody>
<tbody>
<tr>
<td style="text-align:left;" colspan="2"><em>Flat</em></td>
</tr>
<tr>
<td style="text-align:left;"><code>Lin</code></td>
<td style="text-align:left;"><code>Line</code></td>
<td style="text-align:center;">A Direct Line: e.g. <code>Lin lin = Par par ^ Inf(1)</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Dll</code></td>
<td style="text-align:left;"><code>DualLine</code></td>
<td style="text-align:center;">A Dual Line: e.g. <code>Dll dll = lin.dual()</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Pln</code></td>
<td style="text-align:left;"><code>Plane</code></td>
<td style="text-align:center;">A Direct Plane: e.g. <code>Pln pln = Cir cir ^ Inf(1)</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Dlp</code></td>
<td style="text-align:left;"><code>DualPlane</code></td>
<td style="text-align:center;">A Dual Plane: e.g. <code>Dlp dlp =</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Flp</code></td>
<td style="text-align:left;"><code>FlatPoint</code></td>
</tr>
</tbody>
<tbody>
<tr>
<td style="text-align:left;" colspan="2"><em>Versors</em></td>
</tr>
<tr>
<td style="text-align:left;"><code>Rot</code></td>
<td style="text-align:left;"><code>Rotor</code></td>
<td style="text-align:center;">Spins an Element (as a Quaternion would)</td>
</tr>
<tr>
<td style="text-align:left;"><code>Trs</code></td>
<td style="text-align:left;"><code>Translator</code></td>
<td style="text-align:center;">Translates an Element</td>
</tr>
<tr>
<td style="text-align:left;"><code>Dil</code></td>
<td style="text-align:left;"><code>Dilator</code></td>
<td style="text-align:center;">Dilates an Element</td>
</tr>
<tr>
<td style="text-align:left;"><code>Mot</code></td>
<td style="text-align:left;"><code>Motor</code></td>
<td style="text-align:center;">Twists an Element along an axis</td>
</tr>
<tr>
<td style="text-align:left;"><code>Trv</code></td>
<td style="text-align:left;"><code>Transversor</code></td>
<td style="text-align:center;">Bends an Element about the Origin</td>
</tr>
<tr>
<td style="text-align:left;"><code>Bst</code></td>
<td style="text-align:left;"><code>Booster</code></td>
<td style="text-align:center;">Bends an Element around an “Orbit”</td>
</tr>
</tbody>
<tbody>
<tr>
<td style="text-align:left;" colspan="2"><em>Abstract</em></td>
</tr>
<tr>
<td style="text-align:left;"><code>Mnk</code></td>
<td style="text-align:left;"><code>MinkowskiPlane</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Pss</code></td>
<td style="text-align:left;"><code>Pseudoscalar</code></td>
</tr>
<tr>
<td style="text-align:left;"><code>Inf</code></td>
<td style="text-align:left;"><code>Infinity</code></td>
</tr>
</tbody>
</table>
<p>There are others as well (for instance, affine planes, lines, and points) but the above are more than sufficient to start with.
There are also built in macros, for instance </p>
<p><code>EP</code> | Sphere At the Origin.<br/>
<code>EM</code> | Imaginary Sphere at the Origin.<br/>
<code>PT(x,y,z)</code> | A null Point at x,y,z</p>
<p><code>EP</code> and <code>EM</code> can be invoked instead of <code>Inf</code> to work in non-Euclidean metrics ( Spherical and Hyperbolic, respectively)</p>
<p>Many Euclidean elements can be drawn by invoking Draw::Render(<element>). Some can’t (yet) either because it wasn’t obvious
how to draw them (e.g the scalar) or because I just didn’t figure out how to do it or because I forgot or was lazy. If you
want something to be drawable, let me know and I’ll add it in. Or try adding it in yourself and send a pull request via github.</p>
<p>All elements can be dualized by invoking their <code>dual()</code> method </p>
<p>All elements can be reflected over spinors with the <code>sp(<spinor>)</code> method </p>
<p>All elements can be reflected over versors with the <code>re(<versor>)</code> method </p>
<p>The versors are constructed by the geometric entities, typically by using the <code>Gen::</code> routines. Operators can also be acted on by operators – you can rotate a translation, or twist a boost.</p>
<h2 id="reflections">REFLECTIONS</h2>
<p>Most reflections (in a sphere, circle, or point pair, or over a line or plane ) can be calculated by writing</p>
<pre><code>Pnt p = PT(1,0,0);
Pnt r = p.re( CXY(1) ); //Reflection of a point in a circle
r = r / r[3]; //Renormalization of a point
</code></pre>
<p>The re() method calculates <code>v.re(C)</code> as <code>C*v.involution()*~C</code>. With a versor <code>C</code> and an element <code>v</code> you might also try <code>C * v * !C</code>. Inversion in a circle or a sphere may change the
weight of the element (for at Point at x, it will change it by x^2)</p>
<h2 id="links">LINKS</h2>
<ul>
<li><a href="http://vimeo.com/wolftype">Some Video Demos of Versor</a></li>
<li><a href="http://www.geometricalgebra.net/">The Good Book: <em>Geometric Algebra for Computer Science</em></a></li>
<li><a href="http://www.delicious.com/tag/geometricalgebra">GA Bookmarks on Delicious</a></li>
<li><a href="https://groups.google.com/forum/?fromgroups#!forum/geometric_algebra">GA Google Group</a></li>
<li><a href="http://geocalc.clas.asu.edu/">David Hestenes’ Geometric Calculus Page</a></li>
<li><a href="http://www.science.uva.nl/research/isla/">University of Amsterdam Intelligent Systems Lab</a></li>
<li><a href="http://www.gdl.cinvestav.mx/~edb/">Eduardo Bayro-Corrochano’s Robotics Lab</a></li>
<li><a href="http://www.mrao.cam.ac.uk/~clifford/">Cambridge University Geometric Algebra Research Group</a></li>
<li><a href="http://www.mrao.cam.ac.uk/~clifford/">Cognitive Systems at Christian-Albrechts-Universität zu Kiel</a></li>
</ul>
<h2 id="papers">PAPERS</h2>
<ul>
<li>2011 <a href="http://wolftype.com/versor/colapinto_masters_final_02.pdf">Versor: Spatial Computing With Conformal Geometric Algebra</a></li>
<li>2012 <a href="http://versor.mat.ucsb.edu/Boosted_Surfaces_submission_0113.pdf">Boosted Surfaces: Synthesis of Meshes using Point Pair Generators in the Conformal Model</a></li>
</ul>
</body>
</html>