POV-Ray : Newsgroups : povray.advanced-users : Vector Math Problem : Re: Vector Math Problem Server Time
29 Jul 2024 10:28:00 EDT (-0400)
  Re: Vector Math Problem  
From: Christopher James Huff
Date: 6 Jan 2003 11:42:47
Message: <cjameshuff-CFA881.11324706012003@netplex.aussie.org>
In article <web.3e1905318bb9cc14b417814a0@news.povray.org>,
 "Tor Olav Kristensen" <tor### [at] hotmailcom> wrote:

> I think this line;
> #local lRayStart = rayStart - midPt;
> 
> - should have been:
> #local lRayStart = midPt - rayStart;

No, I don't think so. That code is transforming the ray by the inverse 
of a transformation that would translate the plane to its position. This 
is simply a subtraction from the ray origin.


> And there should be no need to normalize the normal vector.

There is. If the normal is twice as long, the intersection will be found 
twice as far away. This could be with the exact same plane, and is 
obviously wrong.


> Here's how I would have written that macro:

Well, remember that I was writing it to both fit in the message and more 
to explain something than to be used.


> And here's how I would test the ray:
> 
> #declare pHit = CompPoint(p0, p1, pRay, vRay);
> 
> #if (vdot(pHit - pRay, vRay) < 0)
>   #debug "There is no point on the ray that has"
>   #debug "equal distances to both points."
> #end

Needlessly complex, but it would work. Here's what I'd use (still highly 
simplified and spread out, though):

#macro CompPoint(pA, pB, rayStart, rayDir, Res)
// The midpoint and plane normal.
    #local midPt = (pA + pB)/2;
    #local Norm = vnormalize(pB - pA);

// Compensate for the plane not passing through the origin.
    #local lRayStart = rayStart - midPt;

// Solve for intersection distance with line.
    #local T = (vdot(Norm, lRayStart)/vdot(Norm, rayDir))

// If T is > 0, there is a ray intersection at rayStart + rayDir*T.
// Otherwise, no intersection.
    #local isectFound = T > 0;
    #if(isectFound)
        #declare Res = rayStart + rayDir*T;
    #end
    
    (isectFound)
#end

#declare hitPoint = < 0, 0, 0>;
#if(CompPoint(pA, pB, rayStart, rayDir, hitPoint))
    ...
#end

Just for fun, a possible over-verbose Sapphire version:
method ComputePoint: result EquidistantTo: pA And: pB AlongRay: ray {
    def midPt: (pA + pB)/2;
    def norm: (pB - pA).(Normalize);
    def t: norm.(Dot: ray.origin - midPt)/norm.(Dot: ray.direction);
    if(t > 0) {
        result = ray.(Evaluate: t);
        return true;
    }
    else {
        return false;
    }
}

def pt: Vector.(Clone);
if(.(ComputePoint: pt EquidistantTo: pA And: pB AlongRay: 
Ray.(RayWithOrigin: orig Direction: dir)))
    ...

(I wouldn't seriously use "ComputePoint:EquidistantTo:And:AlongRay:", 
though...just self-documentation to an extreme. Some Objective-C method 
names get even longer, though...)

-- 
Christopher James Huff <cja### [at] earthlinknet>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: chr### [at] tagpovrayorg
http://tag.povray.org/


Post a reply to this message

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