POV-Ray : Newsgroups : povray.general : Perpendicular to an arbitrary axis Server Time
2 Aug 2024 18:08:34 EDT (-0400)
  Perpendicular to an arbitrary axis (Message 1 to 5 of 5)  
From: Rick Measham
Subject: Perpendicular to an arbitrary axis
Date: 2 Aug 2004 18:05:00
Message: <web.410eba6fcd20604ecbae57f30@news.povray.org>
Thanks to those who helped last week when I needed to find a point on an
arbitrary axis between two points. The vnormalize has worked brilliantly.

Now I come to beg more wisdom from you.

Lets say there's two points: l_source and l_point_at. Last weeks question
gave me l_desitination which is a point on the axis between those two. I've
drawn a cylinder there with a matchine sphere at l_source.

I've hollowed the object and now need to punch some holes around the edge.
These holes have a focal point around the l_source and need to be angled
along the same axis as the cylinder. After learning about vnormalize I went
looking and found a couple of other v___ funtions. Hobbling them together I
got the following:

  union {
   // Put vent holes around the source
   #local x_point = vcross(l_source, l_point_at); // get a perpendicular
   #declare loop_index = 1;
   #while (loop_index <= hole_count)
    #local x_point = vaxis_rotate(x_point, vnormalize(l_source -
l_point_at), 360/hole_count);
    cylinder {
     <0,0,0>
     x_point
     snoot_radius / 20
     translate l_source
     pigment { Yellow }
    }
    #declare loop_index = loop_index + 1;
   #end
  }

Amazingly this works! Almost.

When l_point_at is <0,0,0> or some point along the path between l_source and
<0,0,0> I get a parse error:
Parse Error: Degenerate cylinder, base point = apex point.

I figure it's going to be as easy as extending something a little bit in
some direction somewhere. But where? Help me, O Learned Ones.

Cheers!
Rick


Post a reply to this message

From: Slime
Subject: Re: Perpendicular to an arbitrary axis
Date: 2 Aug 2004 19:30:17
Message: <410ece89$1@news.povray.org>
>    #local x_point = vcross(l_source, l_point_at); // get a perpendicular

Well, if l_source and l_point_at are parallel vectors, then vcross will give
you <0,0,0> as its result.

It looks to me like you're trying to get a vector perpendicular to
l_point_at, but it doesn't matter what vector it is as long as it's
perpendicular.

To get a vector perpendicular to another vector, you just do a vcross with
any other vector:

#local x_point = vcross(x, l_point_at); // get a perpendicular

But this can always pose a problem, since you have to ensure that the vector
you choose (x in this case, l_source in your case) isn't parallel to the
vector you're finding a perpendicular for (l_point_at).

The simplest solution is this:

#local x_point = vcross(x, l_point_at);
#if (vlength(x_point) = 0)
    #local x_point = vcross(y, l_point_at); // if x was parallel to
l_point_at, try y instead
#end

In any case, there is a function in math.inc, VPerp_To_Vector(V), which will
find a vector perpendicular to l_point_at if you do
VPerp_To_Vector(l_point_at). I wouldn't be surprised if it uses the same
method I just mentioned.

 - Slime
 [ http://www.slimeland.com/ ]


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Perpendicular to an arbitrary axis
Date: 2 Aug 2004 20:32:37
Message: <410edd25$1@news.povray.org>
Rick Measham wrote:
> Thanks to those who helped last week when I needed to find a point on an
> arbitrary axis between two points. The vnormalize has worked brilliantly.
> 
> Now I come to beg more wisdom from you.
> 
> Lets say there's two points: l_source and l_point_at. Last weeks question
> gave me l_desitination which is a point on the axis between those two. I've
> drawn a cylinder there with a matchine sphere at l_source.
> 
> I've hollowed the object and now need to punch some holes around the edge.
> These holes have a focal point around the l_source and need to be angled
> along the same axis as the cylinder. After learning about vnormalize I went
> looking and found a couple of other v___ funtions. Hobbling them together I
> got the following:
> 
>   union {
>    // Put vent holes around the source
>    #local x_point = vcross(l_source, l_point_at); // get a perpendicular
>    #declare loop_index = 1;
>    #while (loop_index <= hole_count)
>     #local x_point = vaxis_rotate(x_point, vnormalize(l_source -
> l_point_at), 360/hole_count);
>     cylinder {
>      <0,0,0>
>      x_point
>      snoot_radius / 20
>      translate l_source
>      pigment { Yellow }
>     }
>     #declare loop_index = loop_index + 1;
>    #end
>   }
> 
> Amazingly this works! Almost.
> 
> When l_point_at is <0,0,0> or some point along the path between l_source and
> <0,0,0> I get a parse error:
> Parse Error: Degenerate cylinder, base point = apex point.
> 
> I figure it's going to be as easy as extending something a little bit in
> some direction somewhere. But where? Help me, O Learned Ones.

The code below should work.

I recommend that you read this section in the manual:

http://www.povray.org/documentation/view/3.6.0/49/
(2.1.2.2.2 #declare vs. #local)

- if you haven't already done so.


Tor Olav


// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.6;

#include "colors.inc"
#include "math.inc" // For the VPerp_To_Vector() macro

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Set known constants

#declare NrOfHoles = 6;
#declare CylinderRadius = 0.6;
#declare HolesRadius = 0.2;
#declare pSource = <-3, -2, -2>;
#declare pPointAt = <3, 2, 3>;
#declare DistFromSource = 1.5;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Solve problem

#declare vDir = pPointAt - pSource;
#declare vPerp = VPerp_To_Vector(vDir);

difference {
   cylinder {
     pSource, pPointAt, CylinderRadius
     pigment { color Yellow }
   }
   #declare Cnt = 0;
   #while (Cnt < NrOfHoles)
     #declare pAround = vaxis_rotate(vPerp, vDir, Cnt/NrOfHoles*360);
     cylinder {
       <0, 0, 0>, pAround, HolesRadius
       translate pSource + DistFromSource*vnormalize(vDir)
       pigment { color Red*2 }
     }
     #declare Cnt = Cnt + 1;
   #end
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Shoot

light_source { <3, 6, -4>*10 color White }

camera {
   location <0, 1, -3>*3
   look_at <0, 0, 0>
}

background { color Grey }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Perpendicular to an arbitrary axis
Date: 2 Aug 2004 20:33:52
Message: <410edd70$1@news.povray.org>
Slime wrote:
...
> To get a vector perpendicular to another vector, you just do a vcross with
> any other vector:
> 
> #local x_point = vcross(x, l_point_at); // get a perpendicular
> 
> But this can always pose a problem, since you have to ensure that the vector
> you choose (x in this case, l_source in your case) isn't parallel to the
> vector you're finding a perpendicular for (l_point_at).
> 
> The simplest solution is this:
> 
> #local x_point = vcross(x, l_point_at);
> #if (vlength(x_point) = 0)
>     #local x_point = vcross(y, l_point_at); // if x was parallel to
> l_point_at, try y instead
> #end
> 
> In any case, there is a function in math.inc, VPerp_To_Vector(V), which will
> find a vector perpendicular to l_point_at if you do
> VPerp_To_Vector(l_point_at). I wouldn't be surprised if it uses the same
> method I just mentioned.

It's a little bit different.

-- 
Tor Olav
http://subcube.net
http://subcube.com


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Perpendicular to an arbitrary axis
Date: 2 Aug 2004 20:54:37
Message: <410ee24d$1@news.povray.org>
I read your post again.
Now I suspect that you wanted something like this:

Tor Olav

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.6;

#include "colors.inc"
#include "math.inc" // For the VPerp_To_Vector() macro

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare NrOfHoles = 6;
#declare OuterRadius = 0.6;
#declare WallThickness = 0.1;
#declare HolesRadius = 0.2;
#declare pSource = <-3, -2, -2>;
#declare pPointAt = <3, 2, 3>;
#declare DistFromSource = 3;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare InnerRadius = OuterRadius - WallThickness;
#declare vDir = vnormalize(pPointAt - pSource);
#declare vPerp = VPerp_To_Vector(vDir);

difference {
   cylinder {
     pSource, pPointAt, OuterRadius
     pigment { color Yellow }
   }
   cylinder {
     pSource - 0.01*vDir, pPointAt + 0.01*vDir, InnerRadius
     pigment { color Blue*2 }
   }
   #declare Cnt = 0;
   #while (Cnt < NrOfHoles)
     #declare pAround = vaxis_rotate(vPerp, vDir, Cnt/NrOfHoles*360);
     cylinder {
       <0, 0, 0>, pAround + DistFromSource*vDir, HolesRadius
       translate pSource
       pigment { color Red*2 }
     }
     #declare Cnt = Cnt + 1;
   #end // while
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

light_source { <3, 6, -4>*10 color White }
light_source { <-3, -6, -8>*10 color White }

camera {
   location <-1, 0, -2>*4
   look_at <0, 0, 0>
}

background { color Grey }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

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