DeveloperApps
DeveloperApps

Reputation: 803

A point on a perpendicular line on a specific side

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;

Upvotes: 1

Views: 244

Answers (3)

Jordi Cruzado
Jordi Cruzado

Reputation: 885

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 );

Upvotes: 1

Chuck
Chuck

Reputation: 2102

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;

Upvotes: 0

JonasH
JonasH

Reputation: 36739

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.

Upvotes: 0

Related Questions