POV-Ray : Newsgroups : povray.advanced-users : A macro I'm proud of I think (public Beta) : Re: Beta 2 Server Time
30 Jul 2024 00:22:24 EDT (-0400)
  Re: Beta 2  
From: Tor Olav Kristensen
Date: 14 May 2001 20:27:17
Message: <3B0077E8.76846FC@online.no>
Dan Johnson wrote:
> 
> Ok Tor Olav now that I understand the math I am certain your code works perfectly I
> simplified it enough to remove 3 local variables.  I then added descriptive error
> messages without halting rendering.  There aren't any support functions now.  Unless
> someone thinks of a way to make it better this is the final version.

Your macro looks much better now. And it also 
seems that you have got a better understanding 
of vector dot products now ;)

But I still have some more suggestions for you.
=> See my comments below.


-- 
Best regards,

Tor Olav

mailto:tor### [at] hotmailcom
http://hjem.sol.no/t-o-k/tokpicts.html
http://www.crosswinds.net/~tok


>...
> #macro Four_point_plane(P1, P2, P3, I)// P1-3 = points on plane I = inside point
> 
>   #local Cross = vcross(P2 - P1, P3 - P1);
>   #local STP = vdot(Cross, I - P1); // Scalar Triple Product
>   #if (STP = 0) // Check for invalid data
>     //determine specific error, or errors.
>     #local Errors = "\nFour_point_plane did not create a plane because of the
> following bad imput\n"

>     #local S1 = (vdot((P1 = P2),<1,1,1>) = 3);  // same checks
>     #local S2 = (vdot((P2 = P3),<1,1,1>) = 3);
>     #local S3 = (vdot((P3 = P1),<1,1,1>) = 3);


To "check" if any two points are equal you could write:

#local EqualAB = (vlength(PB - PA) = 0);


>     #if (S1 + S2 + S3 > 0)

You may want to try this:

#if (S1 | S2 | S3)


>      #if (S1) #local Errors = concat (Errors,"Point1 = Point2\n")#end
>      #if (S2) #local Errors = concat (Errors,"Point2 = Point3\n")#end
>      #if (S3) #local Errors = concat (Errors,"Point3 = Point1\n")#end
>     #else
>      #if (abs(vdot(vnormalize(P2-P1),vnormalize(P3-P2))) = 1)

You could simply check if the length of the 
normal vector is 0. (If the length of your 
"Cross" vector is greater than 0, then a
proper normal vector was formed.)


>       #local Errors = concat (Errors,"All points on same line\n")
>      #else
>       #local Errors = concat (Errors,"Inside point is on plane\n")
>      #end

But what if Point1, Point2 and Point3 are 
all on a line, while the "inside point" is 
not on the same line ?


>     #end
>     #warning Errors
>     sphere {<0,0,0>,0}  //Whatever called Four_point_plane is expecting an object.
>   #else
>     #local N = (STP > 0 ? -1 : 1)*vnormalize(Cross);// normal vector
>     plane { N, vdot(P1, N) }
>   #end // if
> 
> #end // macro Four_point_plane
> 
> //  Three_point_plane assumes that the origin is in the object.
> #macro Three_point_plane(P1,P2,P3)
>         Four_point_plane(P1,P2,P3,<0,0,0>)
> #end


Further notes:

If the STP test fails while the normal vector
is found to be "sound" (I.e.: The length of
your "Cross" vector is greater than 0), then
you can deduce from this that the "inside 
point" must also lie within the the plane 
defined by the 3 points: P1, P2 and P3. 

To see this, you may form a vector from the
"inside point" to any one of the other three
points. Now it might be easier to understand
that the only way the dot product between 
this vector and the plane's normal vector 
can be orthogonal to each other (I.e.: their
dot product equals zero) is if the "inside 
point" lies within that plane.



Also note that if you calculate the point-
to-point vectors several times, then this 
will probably slow down your macro bitte-
littegranne.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.