Archive: Two raytracing problems


29th June 2003 13:19 UTC

Two raytracing problems
I've been trying to do some more advanced raytracing and I have two questions. The code can be found in the sections under each question.

---------------
Question 1: I tried making a hyperboloid from one piece using the formule x^2+y^2-z^2=1. So far no problems, but I wanted to view it from the outside. This means the point of origin must lie outside the object with the equation x^2+y^2-z^2=1. I thought that that would be pretty easy to do by changing to the origin coördinates {ox,oy,oz} to {0,2,0} and then I could find out later how to make sure that the position of origin is relative to the rotation angles in such a way that the camera always look at the object.
But after I changed {ox,oy,oz} to {0,2,0} (you can do this changing the following line:


Frame:
ox=0;oy=0;oz=0;

to

Frame
ox=0;oy=2;oz=0;

The view isn't like the object I intended at all. What have I done wrong?
The code of the dynmov:

init
pi=acos(-1);rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0.05;ryo=0.01;rzo=rand(10)/100-0.05

frame
rx=rx+rxo;rxo=rxo*0.9+rxc*0.1;rxc=rxc*0.99;
ry=ry+ryo;ryo=ryo*0.9+ryc*0.1;
rz=rz+rzo;rzo=rzo*0.9+rzc*0.1;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
ox=0;oy=0;oz=0;
c1=ox*ox+oy*oy-oz*oz-1;

beat
rxc=rand(40)/500-0.05;
ryc=rand(40)/500-0.05;
rzc=rand(40)/500-0.05;

point
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
a1=x3d*x3d+y2d*y2d-z3d*z3d;b1=2*(x3d*ox+y2d*oy-z3d*oz);
ki=sqrt(b1*b1-4*a1*c1)/(2*a1);
k1=-b1/(2*a1)+ki;
k2=-b1/(2*a1)-ki;
k=min(k1,k2);
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=abs(atan2(ix,iy))/pi*2;y=iz*3;
alpha=1.3-abs(iz)/2;


---------------
Question 2: I wanted to do a triangular tunnel by defining three planes with the following formulas:

-x+y=2
x+y=2
y=-sqrt(2)

This should give you a triangle tunnel, but instead I get something very strange. There are three planes, which will form a triangle when extended, but on and around the places where the triangle sides should meet, there are some strange planes that go to infinity. Making the k1, k2 and k3 absolute solves the problem, but gives you a six-sided tunnel. I want a three-sided one.
I think the problem has to do with the -infinity outcomes for k1, k2 and k3, but I can't get rid of those without making the tunnel six-sided. The code of the dynmov:

init
pi=acos(-1);rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0.05;ryo=0.01;rzo=rand(10)/100-0.05

frame
rx=rx+rxo;rxo=rxo*0.9+rxc*0.1;rxc=rxc*0.99;
ry=ry+ryo;ryo=ryo*0.9+ryc*0.1;
rz=rz+rzo;rzo=rzo*0.9+rzc*0.1;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
ox=0;oy=0;oz=0;

beat
rxc=rand(40)/500-0.05;
ryc=rand(40)/500-0.05;
rzc=rand(40)/500-0.05;

point
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy)/(y2d-x3d);
k2=(2-ox-oy)/(y2d+x3d);
k3=(-sqrt(2)-oy)/y2d;
k=min(k1,min(k2,k3));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=ix;y=iz;
alpha=1.3-abs(iz)*0.5;

29th June 2003 14:21 UTC

For the second problem:


x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy)/(y2d-x3d);
k1=if(below(k1,0),5000,k1);
k2=(2-ox-oy)/(y2d+x3d);
k2=if(below(k2,0),5000,k2);
k3=(-sqrt(2)-oy)/y2d;
k3=if(below(k3,0),5000,k3);
k=min(k1,min(k2,k3));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=ix;y=iz;
alpha=1.3-abs(iz)*0.5;


Min takes the lowest value, so if k2=-100 and k3=-50, your math would choose k2. I changed the code so it (essentially) takes the number with the lowest positive value, but does not use that number's absolute value. At leat I think that's what I did... It kinda don't look right to me

I haven't worked on the first problem much, but i'll try to figgure it out...

edit: put that code in per point.

edit2: Man i'm dumb... All I did was get rid of all negative k1,k2,and k3 values, I dunno what I was talking about above...

29th June 2003 15:14 UTC

Wow, great, thanks a lot, I now see what I did wrong. 13373571, you'll get a word of thank when I finish my dynmov tetrahedron ;).


29th June 2003 17:51 UTC

In the first one, you use

ki=sqrt(b1*b1-4*a1*c1)/(2*a1);
k1=-b1/(2*a1)+ki;
k2=-b1/(2*a1)-ki;
k=min(k1,k2);

... This has the same problem as the second one... if k1=-13373571 and k2=13373571, you will render the negative value... I don't know if that's your only problem though, I haven't tested because I'm sick of winamp crashing every five minutes... It's enough to make me want to try winamp 2.

And by the way, I *think* you can use

ki=sqrt(b1*b1-4*a1*c1)/(2*a1);
k=-b1/(2*a1)-ki;
k=if(below(k,0),-b1/(2*a1)+ki,k);

and then blend out negative ks...

Wow, great, thanks a lot, I now see what I did wrong. 13373571, you'll get a word of thank when I finish my dynmov tetrahedron .
Yeesh, even thinking about a DM tetrahedron makes my head hurt :D especially if you're going to be viewing it from outside...

edit: Wow I use a lot of ...s, I need to try to stop doing that

30th June 2003 06:03 UTC

13373571, the dm master after UnConeD :D (btw, do you have a nick or something? feels funny to call you 13373571)


30th June 2003 08:35 UTC

Some people have called me "I.P. Address" and "Numbers"...
You can say "leet" or 1337 or any variation thereof. Or just smack your keypad randomly and use the number that comes up.


30th June 2003 14:38 UTC

Looks like LeetEsti to me. ;)


30th June 2003 16:50 UTC

yeah, i thought of that too!


30th June 2003 17:10 UTC

i always thought it was leetest1
like "leetest one".

thanks for the advise though 14234563780, from now on i shall call you 0142387134610..


30th June 2003 19:05 UTC

I made a DM tetraeder. I made it using the following formules for the sides:


x+y+z=2
-x+y+z=2
y+z=-sqrt(2)
z=-sqrt(2)


The code for that dynmov is the following:

init:
pi=acos(-1);rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0.05;ryo=0.01;rzo=rand(10)/100-0.05;

frame:
rx=rx+rxo;rxo=rxo*0.9+rxc*0.1;rxc=rxc*0.99;
ry=ry+ryo;ryo=ryo*0.9+ryc*0.1;
rz=rz+rzo;rzo=rzo*0.9+rzc*0.1;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
ox=0;oy=0;oz=0;

beat:
rxc=rand(40)/500-0.05;
ryc=rand(40)/500-0.05;
rzc=rand(40)/500-0.05;

pixel:
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
k1=if(below(k1,0),5000,k1);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
k2=if(below(k2,0),5000,k2);
k3=(-sqrt(2)-oz)/z3d;
k3=if(below(k3,0),5000,k3);
k4=(-sqrt(2)-oy-oz)/(y2d-z3d);
k4=if(below(k4,0),5000,k4);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1.3-abs(iz)*0.5;


But when I try to view that from the outside, it doesn't look like a tetraeder. The sides 'continue'. It looks like when you see a cube from the outside with all the sides extended infinitely. Using max() instead of min() doesn't work. If you do that, it gets all infinity. I think you have to determine the lines where two planes meet and then use an if()-function to choose min() when inside those lines and to use max() when outside those lines.

I did figure out how to make the camera always point at the center of the object, after looking at UnConeD's WaterCube code. Instead of getting the origin {ox,oy,oz} from the rotation angles {rx,ry,rz}, you determine the rotation angles from the origin. You can do this with atan2(). An example is the following code, which you can paste in the frame section of the dynmov above.

frame:
o=o+or;or=(or*19+oc)*0.05;
ox=sin(o)*3;oy=cos(o)*3;oz=0;
rz=atan2(ox,oy);
rx=atan2(oy,oz);
ry=0;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);


Since oz=0, there's no need to calculate ry.

1st July 2003 01:09 UTC

But when I try to view that from the outside, it doesn't look like a tetraeder. The sides 'continue'. It looks like when you see a cube from the outside with all the sides extended infinitely. Using max() instead of min() doesn't work. If you do that, it gets all infinity.
The reason we were setting the k values to 5000 was because we were using min and there isn't much chance that 5000 will be the minimum value. But when using max, we want the negative values to stay negative so that they aren't selected for rendering.

I think you have to determine the lines where two planes meet and then use an if()-function to choose min() when inside those lines and to use max() when outside those lines.
Lines don't have insides. And we already know how to get the tetrahedron to work from inside the tetrahedron. Please be precise when describing ideas, otherwise it's hard for my puny brain to comprehend. And if you have problems putting your idea into words, it will be even harder for you to put it into code. This isn't just nitpicking, I honestly have no clue what you're saying.

No, I haven't fixed your tetrahedron, I told you earlier that even thinking about a dm tetrahedron made my head hurt, didn't I? It's more complex than a cube... :(

Let's just wait for UCD to look at this.

Edit: And no, six lines that intersect at the four corners of a tetrahedron don't have insides either.

1st July 2003 08:34 UTC

I meant the pieces of the planes that are inside and outside those lines.


1st July 2003 09:07 UTC

You can also make the camera view the orgin by using :

frame:
rx=rx+bx;ry=ry+by;rz=rz+bz;
sx=sin(rx);sy=sin(ry);sz=sin(rz);
cx=cos(rx);cy=cos(ry);cz=cos(rz);
ox=cy*distance;oy=cz*sy*distance;oz=-sz*sy*distance;

beat:
bx=(rand(201)*0.01-1)*sp;by=(rand(201)*0.01-1)*sp;bz=(rand(201)*0.01-1)*sp;

point:
dx=sx*x+cx*y;dy2=cx*x-sx*y;
dz=sy+cy*dx;dx=cy-sy*dx;
dy=sz*dy2+cz*dz;dz=cz*dy2-sz*dz;
...
....
And the rotation will stay random


1st July 2003 11:25 UTC


x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(below(ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iz,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy-oz)/(y2d-z3d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;


It's supposed to calculate ix,iy,and iz for each plane and then if these coordinates are beyond the bounds of the triangle that each plane is going to be "cut" into, it sets k for that plane to be an arbitrary large number (1337). When this is done for all of the planes, we should have the four triangles that make up the tetrahedron. Then supposedly the closest triangle (found with min) should be the proper one.

Unfortunately, it don't work. :(
anybody know why?

1st July 2003 14:11 UTC

The idea seems to be right, but like you said, it doesn't work. My guess is that the way you decide if the coordinates are outside the bounds of the triangle are somehow flawed. The sides of plane z=-sqrt(2) (k3) lie on -ix+iy+iz=2, ix+iy+iz=2, iy+iz=-sqrt(2) and ofcourse z=-sqrt(2), because that the plane itself. Yet you test for -ix+iy+iz=2, ix+iy+iz=2 and iz=-sqrt(2), but not for iy+iz=-sqrt(2). Was that meant like this and if so, why?

I think we should try to solve this first so that when you view the tetraeder from the inside, it's look normal. Then, if we did it correct, moving the origin outside the object, using nixa's code, would give us a nice DM tetraeder.


1st July 2003 14:52 UTC

...... look carefully at each of the triangle cutter-upper lines. For each plane, I tested its intersection with the other three, but not its intersection with itself because that would've been just a tad redundant...

I just realized my error though... I had thought that earlier when you were listing the planes, you were putting them in order. I guess that was a kinda dumb assumption. Anyways, the fix after that is still a tad glitchy, here is the latest attempt:


pixel:
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(below(ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iz,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy-oz)/(y2d-z3d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1-equal(k,1337);


At least we have triangles now... sorta

1st July 2003 16:41 UTC

skupers: this is wrong:
rz=atan2(ox,oy);
rx=atan2(oy,oz);


The problem with your hyperboloid is twofold:
- you're not discarding points behind the camera (k<0)
- you're not discarding points where there is no intersection (b^2-4*a*c < 0 for the quadratic equation).

I won't bother with the tetrahedron, too much trouble :P. Essentially you just raytrace all the front-facing planes, clip all intersectionpoints with the correct triangle and then min the remaining points. A good source for a fast triangle/line intersection test should be the 3D rendering scene. Try flipcode or something.


1st July 2003 18:21 UTC

you're not discarding points where there is no intersection (b^2-4*a*c < 0 for the quadratic equation).
Right, I forgot that sqrt( a ) is in AVS the same as sqrt( |a| ) (try x=i*2-1;y=sqrt(i); in a SSC to see this).

So, this seems to be a good version of the hyperboloid from one space:


init:
pi=acos(-1);rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0.05;ryo=0.01;rzo=rand(10)/100-0.05;

frame:
rx=rx+rxo;rxo=rxo*0.9+rxc*0.1;rxc=rxc*0.99;
ry=ry+ryo;ryo=ryo*0.9+ryc*0.1;
rz=rz+rzo;rzo=rzo*0.9+rzc*0.1;
cx=cos(rx);sx=sin(rx);
cy=cos(ry);sy=sin(ry);
cz=cos(rz);sz=sin(rz);
ox=cy*3;oy=cz*sy*3;oz=-sz*sy*3;
c1=ox*ox+oy*oy-oz*oz-1;

beat:
rxc=rand(40)/500-0.05;
ryc=rand(40)/500-0.05;
rzc=rand(40)/500-0.05;

pixel:
x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
a1=x3d*x3d+y2d*y2d-z3d*z3d;b1=2*(x3d*ox+y2d*oy-z3d*oz);
d1=b1*b1-4*a1*c1;
k1=if(below(d1,0),50000,(-b1+sqrt(d1))/(2*a1));
k1=if(below(k1,0),50000,k1);
k2=if(below(d1,0),50000,(-b1-sqrt(d1))/(2*a1));
k2=if(below(k2,0),50000,k2);
k=min(k1,k2);
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=abs(atan2(ix,iy))/pi*2;y=iz*3;
alpha=2/k-abs(iz)/6/k;


It's really cool and looks kinda like a wormhole ;).

1st July 2003 18:21 UTC

Essentially you just raytrace all the front-facing planes
Uhh, what's wrong with doing the back-facing planes too? It's easier and we're going to be doing min() on k anyways...

I now have a fairly tetrahedral shape going on having fixed a few more obvious stupid errors (not all of which were mine for a change :p I actually looked at skuper's code) but one of the points of the tetrahedron always manages to stretch to infinity and both oy and oz seem to be changing the same value.

The problem isn't with the triangle cutting stuff, that's working great, it's somethin about how dx,dy,dz, and/or ox,oy,oz are being used, they don't do what they're supposed to and I don't see why.


x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(above(k1,0)*below(ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(above(k2,0)*below(-ix+iy+iz,2)*above(iy+iz,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(above(k3,0)*below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iy+iz,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy-oz)/(y2d+z3d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(above(k4,0)*below(-ix+iy+iz,2)*above(iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1-equal(k,1337);

1st July 2003 22:59 UTC

Yeah, it at least looks like a tetraeder now, but I don't know why on of the points goes to infinity. It seems to me z1=-sqrt(2) is the bottom plane. I'll look into it further tommorrow, it's 0:05 AM in the Netherlands now ;).

I now have a fairly tetrahedral shape going on having fixed a few more obvious stupid errors (not all of which were mine for a change I actually looked at skuper's code)
Maybe you could tell me some of those errors, so I don't end up repeating them.

Do you mean oy and oz change per pixel? If so, that isn't happening. You can check that by adding x=x1*oy;y=y1*oz; to the end of the dynmov. They only change per frame (they're ofcourse supposed to do this), not per pixel.

BTW, are you a university student like UnConeD and Jheriko, 1337?

2nd July 2003 01:27 UTC

Maybe you could tell me some of those errors, so I don't end up repeating them.
but.... they were obvious and I'm lazy. Just remember the old adage that "When describing many planes, you are likely to switch subtraction and addition once or twice."

If you set everything to zero (the d's and the o's) and then add small increments to oy and then set it back to zero and do the same with oz, they seem to cause the same changes if I remember correctly.

BTW, are you a university student like UnConeD and Jheriko, 1337?
No :D I'm entering junior year in high school.

2nd July 2003 02:26 UTC

1337: there's nothing wrong with raytracing the backfacing points, but if you can avoid it easily, it's another optimization staring you in the face.

For example for quadrics... the solutions to the equation are something like (-b-sqrt(d))/2a and (-b+sqrt(d))/2a. Because of the way the equation is written down, one of them is always the frontfacing point, and the other is always the backfacing point. If you never switch between inside/outside, then you can always use the same point.

And in Watercube I only raytrace 3 planes rather than 6 because only 3 are ever visible at once.


2nd July 2003 04:14 UTC

with the tetrahedron: its practiaclally impossible to perform any intelegent back-face culling in avs, due to lack of decent control structures.

When you are veiwing it from the exterior, you cant just use max or min, or comninations of both, because you are dealling with infinite planes. Imagine that there is one face of the tertrahedron dirctly flat to the camera (x,y plane), this plane will never shine as the max or min k value becaue the angled planes adjacent to stretch out to infinity, and therfore go infront of it.

To get it to work properly, you would either have to write a backface culling line for each individual plane, or write a limiter for each plane, so that when it reaches the boundries of a particular face, it starts drawin the next plane.

It might be easier to do one DM for each face.

(ucd) Essentially you just raytrace all the front-facing planes, clip all intersectionpoints with the correct triangle
How do you go about clipping the intersection point?

2nd July 2003 06:08 UTC

1337: there's nothing wrong with raytracing the backfacing points, but if you can avoid it easily, it's another optimization staring you in the face.

For example for quadrics... the solutions to the equation are something like (-b-sqrt(d))/2a and (-b+sqrt(d))/2a. Because of the way the equation is written down, one of them is always the frontfacing point, and the other is always the backfacing point. If you never switch between inside/outside, then you can always use the same point.
Yes, I know that (-b-sqrt(d))/2a always gives the lowest k value in a quadratic because 2a and sqrt(d) are always positive. But with a tetrahedron, I see no easy trick to determine weather you are looking at the front or the back of the plane. The only way would be to figure out the relationships between ox,oy, and oz based on each plane's formula that signify weather the camera is "behind" the plane or in front of it, and after that, due to the funky if statements, I only think it would speed it up a little. Cubes are a rare exception: the formulas for their planes are simple and you can use just three planes and shift their distance back and forth to fake 6 planes ( (distance-ox)/dx ). In other words: Skupers can do it if he wants the speed, I don't feel like it.

siddhartha: one DM for each face would require that each DM has knowledge of the locations of the other faces... and each point has to calculate four identical rotations. slow as hell and hard to code, methinks. And you can use min once you've cut the planes into triangles like we've been doing in the last few examples.

2nd July 2003 09:34 UTC

my eight sided dm :)
i understand, there is an extra rotation on the z axis, which i had made for a purpose, but it is not meant to be here and i am not interested in changing it now.


init:
pi=acos(-1)

frame:

t=t+.001+ti*.1;ti=ti*.9;
ox=cos(t)*.6*sin(t*.76+t);
oy=cos(t*.76+1)*.9;
oz=sin(t-1)*cos(t);
rx=0.1+atan2(ox,sqr(oy)+sqr(oz));
ry=atan2(ox,oz);
rz=-atan2(oz,sqr(ox)+sqr(oy));

sx=sin(rx);sy=sin(ry);sz=sin(rz);
cx=cos(rx);cy=cos(ry);cz=cos(rz);
af=max(h,w)/min(h,w);

cz1=cos(-pi/4);sz1=sin(-pi/4);

beat:
ti=.4

point:

y=if(above(h,w),y*af,y);x=if(above(w,h),x*af,x);

dx1=x*cz-y*sz;
dy1=x*sz+y*cz;
dy2=dy1*cx-sx;
dz2=dy1*sx+cx;
dx3=dx1*cy-dz2*sy;
dz2=dx1*sy+dz2*cy;
dx1=dx3*cz1-dy2*sz1;
dy1=dx3*sz1+dy2*cz1;
dx3=dx1;dy2=dy1;

k1=(1-oy-ox)/(dy2+dx3);
k1=if(below(k1,0),(-1-oy-ox)/(dy2+dx3),k1);

k3=(1-oy)/dy2;
k3=if(below(k3,0),(-1-oy)/dy2,k3);

k4=(1-ox)/dx3;
k4=if(below(k4,0),(-1-ox)/dx3,k4);

k5=(2-oz)/dz2;
k5=if(below(k5,0),(-2-oz)/dz2,k5);

k=min(min(k1,k5),min(k4,k3));

x=k*dx3-ox;
y=k*dz2-oz;

x=if(equal(k,k4),k*dy2-oy,x);
y=if(equal(k,k5),k*dy2-oz,y);

2nd July 2003 09:52 UTC

that's great, although it doesn't render from the outside and doesn't help at all with the tetrahedron :rolleyes:

nice work :D


2nd July 2003 10:46 UTC

And you can use min once you've cut the planes into triangles like we've been doing in the last few examples.
true that.. Sorry, i stopped looking at the examples with scrutiny after the first couple. :D

2nd July 2003 13:41 UTC

hehe, this thread turned into a code book :D

btw. this shape is a hedron now, isnt it?

i dont know exactly what a hedron is, leave alone a tetrahedron.


2nd July 2003 14:22 UTC

i dont know exactly what a hedron is, leave alone a tetrahedron.
Then look it up.

Skupers: You ARE absolutely sure that the four planes you posted earlier form a tetrahedron, right? Because it seems to me that they form a triangle tunnel with a plane intersecting it... and it seems to me that that's what AVS is rendering... and it seems to me that improper planes is the only way to explain what AVS is doing.

2nd July 2003 15:29 UTC

I'm almost certain. I made a image to explain how I got the formulas. It's attached.


3rd July 2003 04:57 UTC

wouldn't adding z on all 3 planes make all 3 planes slope downwards?


3rd July 2003 06:22 UTC

A tetrahedron is a four sided 3D object with all faces being triangles. You people are talking about a triangular prism.


3rd July 2003 06:46 UTC

:D


3rd July 2003 07:11 UTC

A tetrahedron is a four sided 3D object with all faces being triangles. You people are talking about a triangular prism.
Zevensoft, we've been talking about taking four planes, cutting them into triangles, and fitting the triangles together. At least that's what I've been talking about ever since skupers said "tetrahedron". We made a triangular tunnel/prism a good while back. WTF do you mean we've been talking about a triangular prism?

3rd July 2003 07:49 UTC

Originally posted by 13373571
wouldn't adding z on all 3 planes make all 3 planes slope downwards?
No, there's a plane z1=-1 to cut the tunnel. At z1=1, using x1+y1=1-z1 gives you x1+y1=0. And if there was something wrong with these formulas, wouldn't we have noticed earlier? Viewing from the outside gives you a tetrahedron.

3rd July 2003 07:57 UTC

Viewing from the outside gives you a tetrahedron.
No it doesn't, that's the problem, remember? It gives us a triangular prism that stretches infinitely in one diagonal direction and is cut by the plane z=-sqrt(2).

Edit:

Here, i just fixed it.


Pixel:

x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(above(k1,0)*below(ix+iy+iz,2)*above(iy,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(above(k2,0)*below(-ix+iy+iz,2)*above(iy,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(above(k3,0)*below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iy,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy)/(y2d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(above(k4,0)*below(-ix+iy+iz,2)*above(iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1-equal(k,1337);


I changed the plane z+y=-sqrt(2) into the plane y=-sqrt(2). That's what was wrong, you had the wrong plane. Blargh.

3rd July 2003 16:24 UTC

Then, it should be y-z=-sqrt(2), not y=-sqrt(2). Sorry for my stupid mistake. :(



x1=x;y1=y;
x1d=x1*cz-y1*sz;y1d=x1*sz+y1*cz;
y2d=y1d*cx-sx;z2d=y1d*sx+cx;
x3d=x1d*cy-z2d*sy;z3d=x1d*sy+z2d*cy;
k1=(2+ox-oy-oz)/(y2d-x3d+z3d);
ix=k1*x3d+ox;iy=k1*y2d+oy;iz=k1*z3d+oz;
k1=if(above(k1,0)*below(ix+iy+iz,2)*above(iy-iz,-sqrt(2))*above(iz,-sqrt(2)),k1,1337);
k2=(2-ox-oy-oz)/(y2d+x3d+z3d);
ix=k2*x3d+ox;iy=k2*y2d+oy;iz=k2*z3d+oz;
k2=if(above(k2,0)*below(-ix+iy+iz,2)*above(iy-iz,-sqrt(2))*above(iz,-sqrt(2)),k2,1337);
k3=(-sqrt(2)-oz)/z3d;
ix=k3*x3d+ox;iy=k3*y2d+oy;iz=k3*z3d+oz;
k3=if(above(k3,0)*below(-ix+iy+iz,2)*below(ix+iy+iz,2)*above(iy-iz,-sqrt(2)),k3,1337);
k4=(-sqrt(2)-oy+oz)/(y2d-z3d);
ix=k4*x3d+ox;iy=k4*y2d+oy;iz=k4*z3d+oz;
k4=if(above(k4,0)*below(-ix+iy+iz,2)*above(iz,-sqrt(2))*below(ix+iy+iz,2),k4,1337);
k=min(k1,min(k2,min(k3,k4)));
ix=k*x3d+ox;iy=k*y2d+oy;iz=k*z3d+oz;
x=(1-equal(k,k3))*ix+equal(k,k3)*ix;
y=(1-equal(k,k3))*iz+equal(k,k3)*iy;
alpha=1-equal(k,1337);


This should work.

3rd July 2003 17:27 UTC

Sorry for my stupid mistake. :(
No problem, everybody screws stuff like that up occasionally.

I was just getting irritated because I couldn't get something to work even though it seemed so clear that it should've been working.