0
\$\begingroup\$

I have the car's current position Vector3 and an API that gets me the closest point on the middle of the road to any Vector3 parameter I send it like

Vector3 returnCenterOfRoad(Vector3 positionToCalculateFrom)

so I thought calculate two relative vectors, one from car's position to a point returned from that method a little ways down the road called pointC and then call that method using the car's current position called pointB (the car's current position would be pointA). Now I can get relative vectors from A to C and B to C and I know when vectors start from the same point but end up away from each other, I can do something like AC - BC but what about in this case when they start away but go to the same point?

Is this even the right way to calculate the current distance to the middle of the road?

Also, how do I know if it's on the right half or left half of the road if the track snakes around so the car's orientation changes, the left half could be right half or vice versa depending on where on the track the car currently is.

Edit: I also have another method

Vector3 returnLineTangentToCenterOfRoad(Vector3 myPoint)

So if I send in my current car position as myPoint, that method will return a unit vector, lets call it tanUnitVec that is tangent to the closest "center of the road" point from myPoint which I can draw using debug.drawline as a vector (myPoint + tanUnitVec) * scalar. Visuzalized with scalar of 2f, I can see that this tangent line is pointing to the origin in the XZ plane and the track is procedurally generated to be in anywhere of the 4 quadrants.

I also have the car's transform in WCS, Velocity, Angular velocity, speed.

Everything mentioned the beginning is also in WCS.

Here is an image of a yellow line I drew with myPoint as my car's current position and redline with myPoint offset forwards a bit from my car. You can see the faint white line that is the origin so the car's current position is in quadrant 1 and moving forwards to quadrant 4 with z-axis up and down and x-axis left to right.

dir vecs

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Can you tell us anything about how returnCenterOfRoad works? We'll need a bit more information from the road to detect whether we're on the left or right side of it. How do you use it to get a point "a little ways down the road" - do you have some information about the road's direction, or a progress parameter around the track? \$\endgroup\$
    – DMGregory
    Mar 26 at 12:07
  • \$\begingroup\$ Distance to the center of the road is just the magnitude of (car location - center of road location). Left/right will need some more information from the road (When I did something similar, I defined the road as a spline of points, and thus I could get point n+1 or n-1 to get the next/previous road center point) \$\endgroup\$
    – Basic
    Mar 27 at 1:39
  • \$\begingroup\$ @DMGregory I've added a pic and more info \$\endgroup\$ Mar 27 at 7:27

1 Answer 1

1
\$\begingroup\$

If you have two points in the same coordinate system (like, say, the world coordinate system), then the vector from one to the other is just their difference, and the distance between them is the magnitude of that vector. i.e.:

Vector3 roadCenter = returnCenterOfRoad(carPosition);
Vector3 fromRoadToCar = carPosition - roadCenter;
float distanceFromRoad = fromRoadToCar.magnitude;

No third vector somewhere father down the road required. (You can think of the "tail" of both the carPosition and roadCenter vectors as sitting at the world origin - so they "start from the same point")

I know when vectors start from the same point but end up away from each other, I can do something like AC - BC but what about in this case when they start away but go to the same point?

When in doubt, draw it:

B-A visualized two ways

B - A is the vector from A's tip to B's tip when both vectors start tail-to-tail, or the vector from B's tail to A's tail when both vectors start tip-to-tip. (Really there, you're measuring (-A) - (-B), flipping which end of each is the "tip" gets you back to the tail-to-tail case).

Now, to figure out if the car is to the left or right of the road, we use the tangent to the road and a cross product:

Vector3 roadForward = returnLineTangentToCenterOfRoad(roadCenter);
// Using left-hand rule: 
// - pose your left hand so your straightened fingers point "up" (1st argument)
// - turn so that as you bend your fingers they curl "forward" (2nd argument)
// - in this pose, your straightened thumb points "right" (output)
Vector3 roadRight = Vector3.Cross(Vector3.up, roadForward);

// Now we check whether we're on the positive or negative side
// of the plane with this normal passing through the road center.
float projection = Vector3.Dot(roadRight, fromRoadToCar);

if (projection > 0) {
    // Car is on the right side of the road.
} else if (projection < 0) {
    // Car is on the left side of the road.
} else {
    // Car is *perfectly* centered on the road.
}
\$\endgroup\$
2
  • \$\begingroup\$ That's pretty awesome, thanks very much. Currently I am using the Vector3.SignedAngle(Velocity, RelativeVectorToCenterOfRoadAheadByOffset) and figured out when I'm on the right or left of the center of the road depending on the sign of the returned angle. \$\endgroup\$ Mar 28 at 8:25
  • \$\begingroup\$ The version in the answer above will tend to be faster, since it uses only basic arithmetic, no trigonometric functions. \$\endgroup\$
    – DMGregory
    Mar 28 at 10:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .