Jump to content

Geometry: 2D point to 1D line


Bloodsong Termagant
 Share

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

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

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_REJECT_TYPES, RC_REJECT_AGENTS | RC_REJECT_PHYSICAL,
                //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;
            
            
            //--SLOPE:

            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

 

Link to comment
Share on other sites

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

default
{
    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.
 

Link to comment
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.

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1722 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...