enkimute / ganja.js Goto Github PK
View Code? Open in Web Editor NEW:triangular_ruler: Javascript Geometric Algebra Generator for Javascript, c++, c#, rust, python. (with operator overloading and algebraic literals) -
License: MIT License
:triangular_ruler: Javascript Geometric Algebra Generator for Javascript, c++, c#, rust, python. (with operator overloading and algebraic literals) -
License: MIT License
Being able to rotate 3D view is great and really adds to the interactive experience of using ganja but it would be fantastic to be able to tilt the camera up and down about the center of rotation by dragging as well as move the center, potentially with the arrow keys?
With large numbers of objects rendered in the conformal visualiser camera rotations become very sluggish and difficult to use
It works fine on chrome, though.
I know it's not a big deal but hey it's worth telling.
Great project, BTW! 🥇
If you have time, consider looking at my own experiments with GA : Clifford (Perl 6) and most recently Clifford.js (javascript).
It's not as advanced as yours, but there may be ideas you could use, like how I used a modified version of the PEGJS javascript example grammar to parse the input.
Support for free-form metric tensors. (request by @darkshikamo / Vincent Nozick)
When using the {data: ...} in the graph the alpha channel appears to be ignored
Example:
https://enkimute.github.io/ganja.js/examples/coffeeshop.html#vR1VaiUqK
Higher dimensional algebras. (Support for an alternate sparse format may need to be considered).
(request by @darkshikamo / Vincent Nozick)
Would be great to be able to change the viewpoint interactively
A minimal reproducer is available here:
https://enkimute.github.io/ganja.js/examples/coffeeshop.html#dq7vtC_pi
Coming from observable, particularly from having seen your Introduction to PGA. (Amazing work, by the way! I'm new to all this, and hope to get a better grip to make things on my own.) One issue with the graphics that looks weird to me is that the line sweeping by should "vanish at the horizon". I haven't tested it out or digged into the code, but I'm guessing you just draw an (infinite) line on the canvas without considering the perspective.
(If you do make the change, you might want to have the line "fade off", instead of abruptly ending at the horizon. I'm only imagining all this, not having seen any actual implementation myself.)
Rendering up(some_vector)^ni
results in a blade of grade 2, yet renders (in CGA3d) as a plane.
In CGA2d (svg), this renders as a point at the origin.
Neither of these seems correct.
I'm trying to draw the camera position + rotation + scale and the orbit center in the CGA visualiser but can't work out a nice way of querying the camera... does this functionality exist? If not would it be difficult to create? I had a dig into the javascript but couldn't work out how to access the M matrix!
The WebGL CGA code leads to an error on IOS and MacOS, chrome or Safari.
12ganja.js:404 Uncaught TypeError: Cannot read property 'enable' of null
It hangs at the gl.enable(...) call, line 404 of the last ganja.js code.
Would allow default settings for displaying scenes and would allow scripting of camera center etc
When working in a specific algebra it is nice to be able to have a full screen view of just the code and the visualisation, it would be nice to be able to hide the top header to get a bigger view
Code generator fails to generate for R666 and similar, the error is:
make GEN_LANG="python" R666
CUSTOM METRIC : 6 6 6
~/ganja.js:542
static lt(a,b) { while(a.call)a=a(); while(b.call)b=b(); return (a instanceof Element?a.Length:a)<(b instanceof Element?b.Length:b); }
^
TypeError: Cannot read property 'call' of undefined
at Function.lt (~/ganja.js:542:33)
at x.map (eval at inline (~/ganja.js:1256:16), <anonymous>:3:223)
at Array.map (<anonymous>)
at eval (eval at inline (~/ganja.js:1256:16), <anonymous>:3:102)
at unops.map.u (~/ganja.js/codegen/generate.js:145:25)
at Array.map (<anonymous>)
at lang.filter.forEach.lang (~/ganja.js/codegen/generate.js:139:26)
at Array.forEach (<anonymous>)
at Object.<anonymous> (~/ganja.js/codegen/generate.js:125:35)
at Module._compile (internal/modules/cjs/loader.js:721:30)
make: *** [makefile:12: R666] Error 1
I was just testing out the nifty new SVG attributes and decided to use a wide drawing canvas using the width:window.innerWidth option to the graph() function. However when I then tried to drag points it appears that the conversion between different coordinate systems isn't taking into account this width. It appears that the input works correctly but it draws the output point as if it were drawing in the smaller default window. When I delete the width:window.innerWidth option (defaulting to a 500 pixel square I think) dragging works like it should. See for example https://beta.observablehq.com/@skydog23/the-polarity-with-respect-to-a-conic, drag the point B. Then remove the width:window.innerWidth option and drag B: everything fine.
Hi @enkimute I am currrently playing around with different javascript GA libraries as I am keen to write a javascript only replacement for my GAOnline project
gaonline.azurewebsites.net
https://github.com/hugohadfield/GAonline
I really like the look of your project but can't seem to find any examples of 3d plotting with 3dcga, any chance you could point me in the right direction?
Hello
The Coffeshop is cool but hard to use on iOS ( iPad ) because of the vertical scrolling that is not static.
May you please implement a body scroll lock in the Coffeshop as exposed here in this link ?
https://www.npmjs.com/package/body-scroll-lock
Do you have any examples of using the chain rule, for (automatic) differentiation?
Hey! The 'inline function' parsing causes some syntax errors, that are notably unsemantic and make debugging a bit weird sometimes. I collected a few below :)
CGA3D.inline(() => {
return [
1, // syntax error
-2,
];
})()
CGA3D.inline(() => {
return [
1, // no syntax error
(-2),
];
})()
CGA3D.inline(() => {
1e5[0]*1e1; // syntax error
})()
CGA3D.inline(() => {
(1e5[0])*1e1; // no syntax error
})()
CGA3D.inline(() => {
const a = 5;
a[0]*1e1; // syntax error
})()
CGA3D.inline(() => {
const a = 5e0;
a[0]*1e1; // no error
})()
Examine feasibility and implementation options (isosurfaces / marching cubes / depthfield rendering / splatting) for rendering high dimensional objects solely by their OPNS. (request by @darkshikamo / Vincent Nozick)
(function() {
var this_fails = 2;
Algebra(3,1,()=>{
console.log(this_fails);
});
})();
gives
this_fails is not defined
at line : 2
would it make sense to allow for point pairs to have a line connecting them? maybe this would be a good way to draw vectors?
While attempting to play around with 3dcga I get a strange type error buried deep in ganga which I am struggling to debug:
TypeError: t is undefined[Learn More]
translate
file:///home/hugo/phd/ganja.js/ganja.js:422:196
translate
file:///home/hugo/phd/ganja.js/ganja.js:427:203
inline
file:///home/hugo/phd/ganja.js/ganja.js:479:100
Algebra
file:///home/hugo/phd/ganja.js/ganja.js:521:40
file:///home/hugo/phd/ganja.js/examples/cga3d.html:16:14
Here is my script:
https://gist.github.com/hugohadfield/ad14fdf02bcf22e2e3eec897a405bb2e
any help with this would be immensely appreciated as the stack trace I get is very hard to decipher for a javascript newbie like myself!
Do we already have formulas in ganja.js
/ CGA for extracting a vector/bivector from a line/plane?
Aflter closely looking at the basis, I'm doing in the following way now. The results seems reasonable.
But is this approach appropriate?
var cga_line_2_g3_dir_vector = (cga_line) => 1e145 << cga_line * 1e1 + 1e245 << cga_line * 1e2 + 1e345 << cga_line * 1e3;
var cga_plane_2_g3_bivector = (cga_plane) => 1e1245 << cga_plane * 1e12 + 1e2345 << cga_plane * 1e23 + 1e1345 << cga_plane * 1e13;
Best,
Hongying
P.S. here is a minimal example: https://observablehq.com/@ying17zi/g3-vector-bivector-extraction-from-a-g41-line-plan-represen
Was getting incorrect results when normalizing, changing abs to fabs solved my problems
ganja.js/codegen/cpp.template.js
Line 175 in 62aefe6
In the generated Python code, __sub__
for int/float and __rsub__
are not correctly implemented.
Take pga3d.py
for example, if we add print(E0 - 1)
to the end of the main function and run it, it will complain:
Traceback (most recent call last):
File "python/pga3d.py", line 469, in <module>
print(E0 - 1)
File "python/pga3d.py", line 278, in __sub__
return a.subs(b)
AttributeError: 'PGA3D' object has no attribute 'subs'
The code reads:
def __sub__(a,b):
"""PGA3D.Sub
Multivector subtraction
"""
if type(b) in (int, float):
return a.subs(b)
res = a.mvec.copy()
res[0] = a[0]-b[0]
# ......
return PGA3D.fromarray(res)
__rsub__=__sub__
If we have fixed this issue and add print(1 - E0)
to the end of the main function and run it, it will print:
-1 + 1e0
which is obvious the negative of the correct result due to __rsub__=__sub__
, as reported by https://discourse.bivector.net/t/bug-in-autogenerated-python-code/49 .
One simple solution is to completely remove the support for multivector/scalar subtraction and vice versa, but this breaks the symmetry of arithmetic and is not preferred.
Any chance of being able to specify point size, line width, and font size in the graph() function, just like color is already supported?
I know this is really stupid, but I was wondering why you need dedicated "times one", "times 2", and so on buttons until I realised they were x
s!
Okay first of all I'm really impressed by your work here... It's inspiring! I have lots of questions but will try to focus on one at a time, starting with this one:
How does your approach compare to the recent binary tree approaches described by Théry & Fuchs here and refined by Ahmad Hosny Eid here?
I noticed that ganja.js allows someone to use a generic Cayley table, so maybe it'd be a pretty complicated project to adopt the binary tree approach in ganja.js.
I'm impressed that your generator can handle that wonderful 15 dimensional Quadric Conformal Geometric Algebra. I've created my own algebraic code generation tools in Python with Sympy, but they rely on symbolic algebra libraries that aren't optimized for lots of dimensions. So that very nice Quadric Conformal Geometric Algebra has been off limits!
Bonus question: do you write the code by hand, or do you use some kind of compiler? It's very "concise"!
I have some reconstruction data that I use ganja to visualise, but would like to be able to move "vertically" as it were rather than being constrained to the plane
http://hh409.user.srcf.net/json_data/reconstruction_html.html
Opening this:
https://enkimute.github.io/ganja.js/examples/coffeeshop.html#cga3d_points_spheres_planes
and dragging any point causes the sphere to dissapear
Often when testing algorithms for working on 3D objects we would like to be able to do a quick scale check against know sized things. A great way of doing this would be via optional graded coordinate axes
It seems that there is a bug with the way scalars are handled in the regressive product for dual numbers, in this case Algebra(0,0,1)
in ganja cheatsheet
(1+2e0) & (3+4e0) = 10+8e0
1 & (3+4e0) = 4
1 & 3 = 3
1 & 4e0 = 4
2e0 & (3+4e0) = 6+8e0
2e0 & 3 = 0
2e0 & 4e0 = 8e0
Thank you for make such great lib, and congratulate that you obtained the Best Paper Award at ENGAGE 2019.
I'm wondering what's your working environment/workflow?
Do you have a minimal working example with Ace and Ganja enabled?
Thanks,
Hongying
P.S. My clone of your coffeeshop does not update on modification and the GA code does not appear. If I click "new", paste example code there, and click "run", the result rendering part does not update either. (The individual examples render correctly; and the result in web browser updates on modification that occurs in external text editor.)
I'm switching to Ganja for geometric analysis, but have never touched web development.
I figured out that you are using Ace (https://github.com/ajaxorg/ace).
I tried to minimize coffeeshop page and also to tweak examples provided by Ace to obtain a working environment. But progress slowly :(.
Examine adding support for respective internal script/file formats for these packages to both reach a larger audience and provide generic visualization support. (feature request @hugohadfield)
Using () => `${(no | ni)}`
as an argument to graph
gives 0
not -1
I really love the "inline functions": instead of a complete DSL, or dealing with a clunky javascript API, you just add operator overloading to otherwise normal javascript code by a clever preprocessing step acting by inflection on the function's defining string. Nice :) This does bring an unintuitive problem though: it breaks lexical scoping:
const a = 5;
console.log(CGA3D.inline(() => {
return a; // nope
})());
A way to deal with this, though a bit cumbersome, is:
const api = { a: 5 };
console.log(CGA3D.inline((api) => {
return api.a; // OK
})(api));
...but might there be a way to reconcile "inline functions" with lexical scoping?
Also, but less important, I'm not sure if "inline functions" is the most logical naming for this feature. What is its rationale?
This is more of a meta issue to track some ideas the came to me during writing the template for Rust:
main()
?This fails with Uncaught TypeError: Cannot read property 'Wedge' of undefined
.
This happens because ninf
and n0
are defined conditionally on the use of g3c, and are not also added for g2c.
Is it possible to specify plane element position in visualizing a plane in ganja.js
?
In my toy example, I noticed that two dual planes are placed/centered along the x-axis.
var dual_plane1 = p1 << (1e1 * ni);
var dual_plane2 = p2 << (1e1 * ni);
I assume this is a preference of ganja.js
.
Is it possible to let the representation centered at p1
and p2
?
Cheers,
Hongying
P.S. In my problem, I'm trying to reconstruct plane elements along a curve, so the position matters. Recommendations of other approaches?
See:
https://beta.observablehq.com/@hugohadfield/conformal-geometric-algebra
Essentially this is about rendering lists of objects without specific names that update dynamically as you move points about... might be a bit of a nasty one... Any alternate api type thing that achieves the same goal would be great!
Namely, up(v)
and 2*up(v)
are rendered as different vectors, when they should be the same.
This is nor a bug nor a pure ganja.js issue but, in an observable notebook, how do we get access to a "viewof" declared variable in a " CGA.inline((f)=>{ ... })(f)
" construction ?
F-Droid maintainer here. You've asked us to include your app with our repository. We're still stuck with that, waiting for you to include the Cordova project folder (we cannot build Cordova apps without that). Any chance for that?
Apologies for this basic question. I recently used Ganja in this notebook and it was great! I tried passing in an object to control the camera position without any success.
Could you modify this code below so that the camera is centered at the origin and the zoom is higher?
P2`this.graph(()=>{
var z = ${v1}
var pm = ${pp.selection.data}
var p=(x,y)=>1e12-(x-1)*1.8*1e02-(y-1)*1.8*1e01;
var a=p(0,0), b=p(z[0],z[1])
var c=p(1.5,1), p=p(pm[0], pm[1])
return [,(1+.9e01)>>>1e1,"y",(1-.9e02)>>>1e2,"x",
0x44AA44,[a,b],0,[a,b],a,"0,0",b,"b",
0x44AA44,[a,c],0,[a,c],a,"0,0",c,"a",
0x44AA44,[a,p],0,[a,p],a,"0,0",p,"p",
0xfdb3b3,[b,p]
]}, { // adding the object here with xpos,ypos etc did not seem to work. })`;
The ability to upload local files of multivectors into the coffeeshop, ideally of the form discussed in pygae/clifford#61, and, additionally to be able to save the same files, would be fantastic and would aid with easy embedding of ganja into desktop apps and offline sharing of visualisations.
Running into performance issues on my laptop when rendering medium/large numbers of spheres and planes, rendering 512 makes this old machine sound like it is going to take off... is there any plan to expand the static rendering mode to circles, spheres and planes? :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.