Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mathematical weakness if a edge line points directly in the center #5

Open
furun opened this issue Jul 17, 2016 · 8 comments
Open

Mathematical weakness if a edge line points directly in the center #5

furun opened this issue Jul 17, 2016 · 8 comments

Comments

@furun
Copy link

furun commented Jul 17, 2016

I ask just for curiosity.
Is there a clean mathematical way to solve the following problem?

There is a Mathematical weakness if a edge line points directly in the center.
So if the two points of a edge are in a straight line to the center (0,0,0).

I speculate, it is the reason for the noise used in Animate::Animate(), to prevent that edge lines point directly in to the center.

Animate::Animate () {
...
    noise0 = 0.005f;
    noise1 = 0.0005f; 

For example:
In this code part the resolut for n b is infinite/NaN, because r3_norm(N) and r3_norm(B) result is 0, if the edge line points to center.

inline float stereo_project (const Vect& x, const Vect& dx, Vect& y, Vect& N, Vect& B) {//projects a tangent vector : R^3 >--> S^3 --> R^3 to normal vectors 
...
    float n = scale / r3_norm(N);
    float b = scale / r3_norm(B); 

Or the Edge tube of such edges gets wobbly because it misses the adjustment.

@fritzo
Copy link
Owner

fritzo commented Jul 18, 2016

Hi furun, I believe (0,0,0) point is the point at infinity, not the point in the center. Jenn3D maps the 3-sphere S^3 onto euclidean space + a point at infinity (which is not drawn). The stereo_project function indeed fails at the singularity at (0,0,0), but this is unavoidable.

The purpose of noise in Animate::Animate is purely aesthetic: it is easier for human eyes to see depth in 3D structure if there is even just a little motion noise.

@furun
Copy link
Author

furun commented Jul 18, 2016

Tanks very much fritzo for the replay!

To explain how this question come up...

I made a little optimisation in r3_norm().
If the sqr result is near 0, it is set to 0. (and near 1 set to 1, to avoid sqrt() for speed. Useful in other code with many 0 and 1 results.)
And i set the noise to 0.

Then i was surprised to see no Edges anymore at the corners in a Hypercube (4,2,2,3,2,3;2,3,4).
Without noise and without the sqrt() optimisations in r3_norm(), the tubes in the same edges get wobbly.

(I teached math to my self, this code is a bit about my level ;-)

@furun
Copy link
Author

furun commented Jul 20, 2016

So much i understand, are no points or edges in infinity in a Hypercube on start position.
It is a gen=2,3,4 form. Not one of for example the gen=1,2,3 witch generates infinite Geometrie.
(not sure if i unterstand you right?)

Here a illustration of the problem.
The noise hides this behavior, because it moves the edges a little of center, and gives the edge a little bow, it is then not a exact straight line anymore..
HyperCube

Noise=0, modified r3_normal() function:
If the edge lines of the Hypercube pointing directly towards (0,0,0), the code in stereo_project "r3_norm(N)" is = 0, and produces a 1/0 error.
The tube diameter step by step is destroyed, wen the geometry comes back from drifting to start position.
The tube diameter could be defined in a difference way, wich not destroys the information of the diameter, in this special case.
I worked on a solution, but have not found any now.

In drift
lost1
Back to start
lost2 lost3
lost4 lost5

Noise=0, original r3_normal() function:
Because there is a little error in flouting point calculations, the original code always has a very small value left in r3_norm(N), r3_norm(B).
Now a other problem shows up, in this special case wen edges pointing directly towards (0,0,0).
The tube gets wobbly, wen the geometry comes back from drifting to start position.
I speculate, the normal direction of the edge is lost, because it is defined be using the edge direction away from (0,0,0). (This is just a speculation, i have not proofed jet.)

In drift
wobbly1
Start
wobbly2

(Why the effort? It is one of the most coolest math software i know :-)

@fritzo
Copy link
Owner

fritzo commented Jul 20, 2016

Cool, yes that looks like a bug indeed! Also, you can switch to wireframe
mode by pressing 'q', which is helpful for debugging. It might also help to
log/print a warning if any denominator is too close to zero. You could do
this at a bunch of places in the code to find which one is triggering.

You're right that in the projection of the hypercube you're examining,
there are no points at infinity at the start position. BTW the N and B in
the code you pointed me to are the Normal and Binormal vectors. It looks
like one or both are ending up zero.

Let me know if you find a fix!

On Jul 20, 2016 6:00 AM, "furun" notifications@github.com wrote:

So much i understand, are no points or edges in infinity in a Hypercube on
start position.
It is a gen=2,3,4 form. Not one of for example the gen=1,2,3 witch
generates infinite Geometrie.
(not sure if i unterstand you right?)

Here a illustration of the problem.
The noise hides this behavior, because it moves the edges a little of
center, and gives the edge a little bow, it is then not a exact straight
line anymore..
[image: HyperCube]
https://camo.githubusercontent.com/8b4f99d19412b915234568448614ca0321d5bed6/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f732f6670727231373872736f3878776d372f4879706572437562652e706e67

Noise=0, modified r3_normal() function:
If the edge lines of the Hypercube pointing directly towards (0,0,0), the
code in stereo_project "r3_norm(N)" is = 0, and produces a 1/0 error.
The tube diameter step by step is destroyed, wen the geometry comes back
from drifting to start position.
The tube diameter could be defined in a difference way, wich not destroys
the information of the diameter, in this special case.
I worked on a solution, but have not found any now.

In drift
[image: lost1]
https://camo.githubusercontent.com/9ff80c1b92c9528bc9ca23a2994b431d779ce272/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f732f6336313665656a77613539623833722f6c6f7374253230312e706e67
Back to start
[image: lost2]
https://camo.githubusercontent.com/cc6877524c0e380cabf9ebf39d9da02481e020ae/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f732f32396a6f6a667369306e76386e63642f6c6f7374253230322e706e67 [image:
lost3]
https://camo.githubusercontent.com/f8b4126aeca63533da573b7bc4e62ba24f674364/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f732f756b6f727368716f7732397a397a6b2f6c6f7374253230332e706e67
[image: lost4]
https://camo.githubusercontent.com/76fecbfdff1d76e7ae664fbff2f0fb4210060fe7/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f732f6d353261786f7735686e34693435622f6c6f7374253230342e706e67 [image:
lost5]
https://camo.githubusercontent.com/ccc67c0f5b26765fe1f84ea8cc1d139828b814d6/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f732f396c39793338647a6a746e626577362f6c6f7374253230352e706e67

Noise=0, original r3_normal() function:
Because there is a little error in flouting point calculations, the
original code always has a very small value left in r3_norm(N), r3_norm(B).
Now a other problem shows up, in this special case wen edges pointing
directly towards (0,0,0).
The tube gets wobbly, wen the geometry comes back from drifting to start
position.
I speculate, the normal direction of the edge is lost, because it is
defined be using the edge direction away from (0,0,0). (This is just a
speculation, i have not proofed jet.)

In drift
[image: wobbly1]
https://camo.githubusercontent.com/685ded89b5d1371441a3f801f2288beabb28aa10/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f732f36366c6a36656a3075626a7a747a642f776f62626c79253230312e706e67
Start
[image: wobbly2]
https://camo.githubusercontent.com/f43b3944f86f7492f3dc1c7c8d03d33436d2a667/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f732f35786d64716369317162787831616b2f776f62626c79253230322e706e67

(Why the effort? It is one of the most coolest math software i know :-)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#5 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAnlVGVgIz4XJz_MhB7WcLMGePYZMKYtks5qXhvXgaJpZM4JOT_k
.

@furun
Copy link
Author

furun commented Jul 21, 2016

OK... i tray, but don't laugh, like i said, i have not study math at uni, only self learnt skills.

I speculate that the cross product for normal and binormal has to be done in 4D space, for this stereo_project.
Projected in 3D, the vector looses the needed info in case of a straight line to center.
point1 and tangent are pointing in the same direction, it is basically the same vector.
Similar like in a Gimbal-Lock problem, the geometric info is lost.
But i have not figured out jet which 3. vector should be used for this, beside of point1 and tangent, in the 4D cross product.

Do you have a tip? In case me idea is right.

(Probable the wobbly tube can be fixed in a similar way.)

@furun
Copy link
Author

furun commented Jul 27, 2016

I understand the problem a bit better now.
The normal and binormal are defined by the tangent of the curvature.
In case of no curvature / straight line, the normal vectors can not be calculated, its (0,0,0), it not defined / it is everywhere.
And the tube gets wobbly beschaue the normal is everywhere, without a curvature or arc defining the direction. Near to the float precision it gets wobbly, on 0 the math gets infinite.

(Jenn crashes internally, the objects disappears from screen. This happens after some minutes, wenn one of the 1/0 situations happen.)

In the stereographic projection is the only situation wenn edges has no curvatures, if they point straight to the center. every other edge will have a curvature.
To move the cross product to 4D not solves the problem, without the stereographic projection to 3D, in 4D are no curvatures at all.

I found no math solution jet. Maybe there is non(?)
A special handling near to 0 is not really beautiful, and will cause a distortion along the edge. Like on the pictures, wenn the edge step by step disappear, it will step by step twist instead.
The only way i see now is to use the adjoining edges instead of the curvature, to define the geometry(?)

@fritzo
Copy link
Owner

fritzo commented Jul 27, 2016

Great deubgging, that sounds plausible to me. I think it's fine to add special handling around zero for the normal and binormal vectors. What if you do something like:

  • if away from zero, use existing N, B computation.
  • if near to zero, choose the most-normal basis vector among (1,0,0), (0,1,0), or (0,0,1). Fix this to be actually normal, and set as N, Compute B as usual.

@furun
Copy link
Author

furun commented Jul 27, 2016

I think this is the best solution for now. To use adjoining edges like i supposed before, did not work either. At least not so easy.
Such near 0 exception handlings are not so elegant, but it will work. To use most-normal will avoid all 1/0 errors.
I tested this quick already with a simple up-vector (0,1,0), before i tested the adjoining-edges idea.
But you will see that the tubes twist along the edge, if they comes back from drift. You can test it with a big near-0 limit like 0.1.

(Tanks for this code! i spend now quite some free time with it.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants