Jump to content
Bloodsong Termagant

Geometry: 2D point to 1D line

Recommended Posts

i think i figured out what i'm doing wrong.


i am trying to calculate the angle of a slope between two points.

point 1 = the spot directly below the avatar where it is standing. (in region coordinates)
point 2 = the spot the ray intersects the ground ahead of the avatar. (in region coordinates, translated from the avatar's local forward axis)

and i have this formula:

angle =  RAD_TO_DEG*( llAtan2(
                    (p2.z - p1.z),(p2.x - p1.x)

i THINK the problem is, that i'm just using the X and Z coordinates, and not correcting for the Y coordinate, if the avatar is not facing along the global X axis.

so i found this: https://www.euclideanspace.com/maths/geometry/elements/projections/index.htm

how to project a point (my target hit with x,y coordinates) onto a line (the global x axis).


um... okay, so i have to take the line that is the avatar's facing, project a line at a right angle to that line from the point, and find out where it hits the X axis.  uh... yeah, i dunno how to do that :/  except by drawing on graph paper! :X  drawing:  https://prnt.sc/onjtdl

okay, i worked THIS out:  http://prntscr.com/onk6ao

if i can just get the x/y plane distance of a, then calculate the x/y coordinate of 2a along the avatar facing... THAT x coordinate should be the one i need.  and i don't need to mess around with all those pythagorean thingies.  what's the 2d version of llVecDist?  oh, set the Zs to 0 first...


okay, i came up with this, and it returns total BS.  it even returns different answers if i click it (activate the calculation by touch) multiple times, without moving in between.

float getSlope()
		float ht = 0.75; //--normally a calculated global.
        vector pos = llGetPos();
        //--we know where the floor is, cuz we're standing on it @ -ht.
        vector target = pos;
        rotation rot = llGetRot();
        target = pos + <3.*ht,0.,0.> *rot;//-- test 3 ahead and 2.5 down
        target.z = target.z - 2.5*ht;

   // llOwnerSay("Aiming "+(string)pos+" to "+(string)target);
        list res2 = llCastRay(pos, target,
                //RC_DATA_FLAGS, RC_GET_NORMAL,
                RC_MAX_HITS, 1]);
llOwnerSay("RC returned:"+llDumpList2String(res2, ","));
        float angle;
        if(llList2Integer(res2, -1) != 0)
           vector p1 = pos;
           vector p2 = llList2Vector(res2, 1);
          //--calculate X without Y   
            vector xy1 = p1;
            vector xy2 = p2;
            xy1.z = 0.0; //--get rid of Z influence
            xy2.z = 0.0;
            float dist = llVecDist(xy1,xy2);
            vector xTarget = pos + <2*dist, 0., 0.> * rot;

            p1.z -= ht;  //--make this the floor
            p1.x = xTarget.x; //--make this our actual distance along avatar FWD
            angle =  RAD_TO_DEG*( llAtan2(
                    (p2.z - p1.z),(p2.x - p1.x)
        else  //--we didn't hit anything, the slope is WAY down.
        angle = -45.0; //--midway to down. fudged.

        if(angle > 90.0) angle -= 180.0;
        else if (angle < -90.0) angle += 180.0;

       return angle;

and no, i don't know how to do angle math, either :X


Share this post

Link to post
Share on other sites

You seem to be overthinking things.  Try this ...

    touch_start(integer total_number)
        vector vHere = llGetPos();  // Here I am
        float fGroundHere = llGround(ZERO_VECTOR);		// Here's the ground under me
        vector vThere = llGetPos() + <20.0,0.0,0.0>*llGetRot();		// This is 20 m in front of me
        float fGroundThere = llGround(vThere - vHere);	// This is the ground 20 m in front of me
        float fDist = llVecDist (<vThere.x,vThere.y,fGroundHere>,<vHere.x,vHere.y,fGroundHere>);  // Here's the horizontal distance between the spots
        float fSlope = llAtan2((fGroundThere - fGroundHere), fDist );	// And here's the calculated slope
        llSay(0, "Slope in radians = " + (string) fSlope + "   Slope in degrees = " + (string)(fSlope*RAD_TO_DEG) );

You'll have to make appropriate adjustments if the surface under you isn't the land surface, but the principle will be the same.

Share this post

Link to post
Share on other sites
1 hour ago, Bloodsong Termagant said:

i am trying to calculate the angle of a slope between two points.

Unclear what that means. Two points do not define an angle. It takes three points.

You want ground slope, right. OK.

vector p1; // point on ground under avatar
vector p2; // point on ground ahead of avatar
vector movedir = llVecNorm(p2-p1);	// direction moving between points
float zlen = movedir.z;			// height of triangle
float xylen = llVecMag(<movedir.x, movedir.y,0>); // base of triangle 
float slopeangledeg = RAD_TO_DEG*llATan2(zlen, xylen); // ground slope as an angle in degrees.
//	Traditional slope (1 m rise in 10 m horizontal => 0.1 slope) if you want that	
float slope = zlen / xylen;		// but will divide by 0 if vertical.


Share this post

Link to post
Share on other sites



i saw that what i was doing was TOTALLY wrong... especially as y approached zero...

thank you so much, for helping me untangle THAT mess.  i'm still trying to picture what's going on... but the formula is working!


and i will definitely have to bookmark that, kyrah!

  • Like 1

Share this post

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...