Home > front end >  A point on a perpendicular line on a specific side
A point on a perpendicular line on a specific side

Time:04-22

I have a point P1 and P2 (this gives me a Vector that has a direction and a turn)

How to determine P1L and P1R?

L is always on the left side and R is always on the right side (no matter how the line is marked)

enter image description here

In the code below, I add and subtract values, but that doesn't tell me when it's going to be right and left.

I would like to point specifically to the point to the left and right as I stand in P1 and look towards P2

Vector2 vNormalized = (endP - startP).normalized;
Vector2 vPerpendicular = new Vector2(vNormalized.y, -vNormalized.x).normalized;

var P1 = startP   vPerpendicular * Thickness / 2;
var P2 = startP - vPerpendicular * Thickness / 2;
var P3 = endP - vPerpendicular * Thickness / 2;
var P4 = endP   vPerpendicular * Thickness / 2;

CodePudding user response:

You are almost there. P1 and P2 will always be clockwise/counterclockwise compared to the direction of the line.

If you want P1L and P1R to be on the Left/right side relative to the viewer you can simply compare the X-coordinate and switch the order of them. or you can switch the sign of the line direction:

if(vPerpendicular.X < 0){
    vPerpendicular = -vPerpendicular;
}

That should ensure that P1 and P2 has a consistent left/right order. But you might need to change the check to vPerpendicular.X > 0 depending on the desired order. It might depend on the coordinate system you are using.

Also, there should be no need to normalize twice. Once should be sufficient.

CodePudding user response:

Find the rotation angle from P1 to P2:

Vector2 diff = P2 - P1;
float angle = Mathf.Atan2(diff.y, diff.x);

Add 90 degrees to the angle to get the angle to P1L. Note that Mathf.Atan2 will return angles in radians:

float P1L_angle = angle   0.5*Mathf.PI;

Now pick some length p1l_length and use sine and cosine to get the x/y values:

float P1L_length = 0.5f;
Vector2 P1L = P1L_length*(new Vector2(Mathf.Cos(P1L_angle), Mathf.Sin(P1L_angle)));

Without offsetting by P1, the P1R is just the opposite of P1L

Vector2 P1R = -P1L;

And then you add P1 to both to get your final answer:

P1L  = P1;
P1R  = P1;

CodePudding user response:

You can think in 3d and it will be easier:

You have your P1-P2 vector in 3d:

Vector3 v = new Vector3( vNormalized.x, vNormalized.y, 0.0f );

and the normal vector:

Vector3 normal = new Vector3( 0.0f, 0.0f, 1.0f );

Then by using Cross product you can calculate the left and right vectors:

Vector3 perpendicularLeft = Vector3.Cross( v, normal ).normalized;
Vector3 perpendicularRight = Vector3.Cross( normal, v ).normalized;

And then you can calculate your points as:

Vector3 PLeft = startP   Thickness * perpendicularLeft;
Vector3 PRight = startP   Thickness * perpendicularRight;

Where:

Vector2 left = new Vector2( PLeft.x, PLeft.y );
Vector2 right = new Vector2( PRight.x, PRight.y );
  • Related