0
\$\begingroup\$

I have a simple setup:

A rectangular object on a coordinate plane, with an orange line drown from its pivot point to hit a white line perpendicularly

How do I calculate the orange distance?

It's the distance between the block on the left to the white line in the center (X & Z axes combined).

I don't have the intersection point. My only knowledge of the white line is that it goes through the point (0, 0, 0), running between (10, 0, -10) and (-10, 0, 10)

A 3/4 view of a scene with the ends of the white line labelled with coordinates

My problem is that I need to calculate this distance without the depth (Y value). Only on two planes combined: X & Z

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Maybe you can use Vector3.Project with normal = new Vector3( 1, 0, 1 ) ? \$\endgroup\$
    – Hellium
    Jul 3 '17 at 13:19
  • \$\begingroup\$ How do you define the white line? Do you know any point on the white line, and the direction the line is pointing? Or do you define it in some other way? \$\endgroup\$
    – DMGregory
    Jul 3 '17 at 14:42
  • \$\begingroup\$ Hey Gregory, I've edited the question :) \$\endgroup\$
    – Jacob
    Jul 3 '17 at 15:11
  • \$\begingroup\$ Edited it again, I've added the image from the wrong angle. Now it's ok. \$\endgroup\$
    – Jacob
    Jul 3 '17 at 15:14
1
\$\begingroup\$

I think you should be able to get the position vector using Vector3.Project

enter image description here

 Vector3 vector = yourGameObject.GetComponent<Transform>().position ;
 vector.y = 0 ;
 Vector3 onNormal = new Vector3( 1, 0, 1 ) ;
 Vector3 projectionOnWHiteAxis = Vector3.Project( vector, onNormal ) ;
 float distance = (projectionOnWHiteAxis - vector).magnitude ;
\$\endgroup\$
1
\$\begingroup\$

You can rotate the point by -45 degrees, so that the x component becomes the distance.

If you always want to find the distance between the point and the XZ axes, then you can just precalculate the values:

| cos -45° -sin -45° |   | √2/2, -√2/2 |
| sin -45   cos -45° | = | √2/2,  √2/2 |

If we take the vector (x; y) the result is:

(√2/2 * x - √2/2 * y; √2/2 * x + √2/2 * y)

Then the distance is abs(√2/2 * x - √2/2 * y)

\$\endgroup\$
6
  • \$\begingroup\$ Yeah, pythagoras would be nice, If I new the intersection point of lines white and orange. My only info is that it's the X & Z axes combination. \$\endgroup\$
    – Jacob
    Jul 3 '17 at 12:56
  • \$\begingroup\$ @Spectre It wasn't clear that you didn't know where the white line was, let me try to figure it out \$\endgroup\$
    – Bálint
    Jul 3 '17 at 13:00
  • \$\begingroup\$ @Spectre Here you go \$\endgroup\$
    – Bálint
    Jul 3 '17 at 13:15
  • \$\begingroup\$ @Bálint don't forget to put the absolute value to your result, otherwise you might be getting negative values depending on (x,y). Also you might want to use 1/sqrt(2) instead of sqrt(2)/2. Mathematically is the same, but less operations ;) \$\endgroup\$
    – Turms
    Jul 7 '17 at 12:39
  • \$\begingroup\$ @Turms sqrt(2) / 2 is actually less CPU intensive, than 1/sqrt(2), because in the latter you need to calculate the square root of 2, then divide 1 with the result (division is hard), while the former only needs to calculate square root of 2 then use a bit shift. You're right about the absolute value though \$\endgroup\$
    – Bálint
    Jul 7 '17 at 13:33
1
\$\begingroup\$
float SignedDistanceFromLine(
    Vector2 sourcePoint, 
    Vector2 lineDirection, 
    Vector2 pointOnLine = default(Vector2))
{
     // Translate the whole situation to the origin.
     sourcePoint -= pointOnLine;

     // Construct a unit vector pointing 90 degrees right of our lineDirection.
     Vector2 perpendicular = (new Vector2(
               lineDirection.y,
              -lineDirection.x)).normalized;

    // Extract the component of our offset pointing in this perpendicular direction.
    return Vector2.Dot(sourcePoint, perpendicular);
}

This returns a signed distance, with positive values signalling that the sourcePoint is to the right of the line, and negative values to the left.

You can use this to get the positive distance like so:

Vector2 objectPosition = new Vector2(
               objectTransform.position.x, 
               objectTransform.position.z);
float distance = Mathf.Abs(SignedDistanceFromLine(objectPosition, new Vector2 (1, -1)));
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.