Jump to content

cast rays fanning out from central point


Judy Hynes
 Share

You are about to reply to a thread that has been inactive for 963 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I got stuck trying to figure out how to orient rays so I thought I'd ask about the math here.  What I want to do is use llCastRay to generate several rays all emanating from the same point but at different angles.  These will be in a script attached to an avatar, so everything will be relative to the avatar's rotation.  I know how to make a ray go straight out in the direction the avatar is facing:

float ray_range = 100.0;
vector ray_start = llGetPos();
vector ray_end = ray_start + <ray_range, 0.0, 0.0>*llGetRot();
list ray_results = llCastRay(ray_start, ray_end, []);

And I know how to make other rays that are parallel to but offset from the center ray:

float ray_range = 100.0;
float left_shift = 2.0;   // this ray will be parallel to center ray from before but 2m left and 3m up from it
float up_shift = 3.0;
vector ray_start = llGetPos() + <0.0, left_shift, up_shift>*llGetRot();
vector ray_end = ray_start + <ray_range, 0.0, 0.0>*llGetRot();
list ray_result = llCastRay(ray_start, ray_end, []);

But I'm struggling with how to make a ray that's for example pointing 5 degrees to the right of the center ray, or pointing 2 degrees up from it.  My example above is easy because the rotation is not adjusted (all rays are parallel so the rotation doesn't change) but I'm not sure how to modify that rotation with an angle offset.

Link to comment
Share on other sites

Just calculate how far the target has to be offset from "straight ahead".

offset = distance * sin( angle) ,  so if you want to aim at a point 10 degrees above a point that's 20m straight ahead of you

distance = 20.0

offset = 20.0 * llSin(10.0 * DEG_TO_RAD)

So you are aiming at a spot that is at   llGetPos() + <20.0, 0.0, offset>*llGetRot()

default
{
    touch_start(integer total_number)
    {
        float dist = 20.0;
        float offset = dist * llSin(10.0*DEG_TO_RAD);
        llSay(0, "Straight ahead = " + (string)( llGetPos() + <20.0,0.0,0.0> * llGetRot()));
        llSay(0, "Aiming 10 degrees up at = " + (string)(llGetPos() + <20.0,0.0,offset> * llGetRot()));
    }
}

 

Edited by Rolig Loon
typos. as always.
Link to comment
Share on other sites

You could do it the fancy rotation way:

vector start = <2,3,1>;
vector end = <2,5,1>; // example data.
// rotate end 5 degrees about the z axis ("to the left")
// on a circle with center at start:
float angle = 5*DEG_TO_RAD; // would be better to do in radians directly but easier this way for an exmaple.
end = start + (end-start)*llAxisAngle2Rot(<0,0,1>,angle);
// . . .

// rotating "up" or "down" is a bit trickier, but this is how I would interpret
// "rotate end up 5 degrees with respect to start"
float angle = 5*DEG_TO_RAD;
vector cross = (end-start)%<0,0,1>; // vector that points 'to the right' of end-start
// in the case where (end-start) is a vector with X as the only non-zero componenet, you coud just set cross to <0,1,0>;
end = start + (end-start)*llAxisAngle2Rot(cross,angle);

 

Edited by Quistess Alpha
Link to comment
Share on other sites

Great, this is just what I needed to understand.  Thanks so much for the help!

I think I'm going to go with the solution suggested by Rolig.  The trigonometry of how to find the end point just makes more sense to me that way. I'm afraid I still get lost in trying to understand how to apply rotations correctly.

 

Link to comment
Share on other sites

45 minutes ago, Judy Hynes said:

the solution suggested by Rolig.

The more I examine it, the more I'm coming to the conclusion that Rolig's method is a bit off. (trig is hard)

I think you actually want offset = distance* tan(angle);

Also be sure not to use angles too close to +/- 90 degrees.

(or if you want to use both trig functions: . . .)

rotateZ(float dist,float ang)
{ // return a vector with length dist and angle ang from the x-axis.
  // be sure ang is in radians.
  return dist*<llCos(ang),llSin(ang),0>;
}
rotateY(float dist, float ang)
{
  return dist*<llCos(ang),0,llSin(ang)>;
}

 

Edited by Quistess Alpha
Link to comment
Share on other sites

You may be right, Tessa.  It depends on where you put the right angle. As long as the angle is reasonably small, the difference shouldn't be great, though.  sin(10 deg) = 0.17365; tan(10 deg) = 0.17633.  The error is about 1.5%. It creeps up to about 10% when the angle is 25 degrees, so that's more significant.  

Link to comment
Share on other sites

14 minutes ago, Rolig Loon said:

As long as the angle is reasonably small

if the angle is reasonably small, you can get away with sin(a) ~= a. which honestly, I was thinking of recommending for largeish angles as well.

(still marginally accurate at 45 degrees = 0.78 radians; sin = 0.7071; tan = 1.0 )

Edited by Quistess Alpha
Link to comment
Share on other sites

  • 2 weeks later...

Just saw this correction.  I used the original solution (sin) and it worked fine.  The angles I need to use are indeed small (around 1 degree) so I guess that switching to the "correct" solution won't look much different.  I made a visualizer that would rez objects at regular intervals along the path to see the "fan out" effect at 5m, 10m, 15m, etc. and it looked like what I wanted.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 963 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...