Vectors question!

Hello BlenderArtists!
I have a question relating to vector comparison.
I am creating a racing positioning system, and i need to find the direction of a segment of track. I had the idea to use the cross product of the start of the segment (x) and the world (z) to yield the Y axis.
However, because of the nature of cross product, if i get the x axis vector as opposite

e.g a-b -> b-a
the y axis is inverted in some cases, because of the nature of obtaining the vertices.
So i ask you, can you think of a way of getting a segment direction as an alternative method? Or how can i fix my problem? Many thanks!

Are you trying to get a cars orientation relative to the worlds orientation, or relative to the tracks orientation?

Actually, there was an episode of “Adventures in Game Development” that covers the basic algorithm:

That should work well enough for most racing games.

There is also a more “mathematical” method, which uses the equation of a curve as a “track guide”, and projects the position of the racers to that curve - but this is, from what I understand, done in 2D space (throw away the Z axis).

So, it’s essentially a transformation from 3D to 2D to 1D (you’re trying to solve for time “t” in the curve function, which then indicates “rank”).

… There was one more interesting method I read about, which utilizes vector fields to do this in a very clever way, but I can’t remember the relevant details - sorry.

Place sequentially numbered empties at key points on the track. (Anywhere the track turns significantly- you’ll figure out the behaviour.) Pull these into a script via object name (perhaps by generating the sequential names, if there are a lot of empties) and store them in a list.

Search and find the empty closest to the racer. Then check the empties sequentially before and after the closest, and again select the one the racer is closest to.

Put the two indices in sequential order with an if/else clause. (So that, basically, you have the two points before/after the racer’s current position.)

i0 = index of first empty
p0 = position of first empty
p1 = position of second empty
pr = position of racer

pos = (i0 + (p1 - p0).length / (pr - p0).length) / len(array of empties) + number of laps done (found by another method)

Tada. Calculate for each racer and compare to find the rankings.

This doesn’t find the distance along the track in any useful sort of unit, but it will work for comparative purposes.

Hope this helps/works.

Trying to pull data from the track polygons seems impractical…
Is there something wrong with method I proposed?

Essentially yes!
Whilst that method i’ve used before will give you positions;
a)it requires hard coded empties, or at least numbered empties
b)It will give an incorrect figure: If you imagine this scenario:

An empty is centered in the track. Three cars are in row, all aligned with each other. Taking a distance reading to the empty will give the most central car a shorter distance, meaning that it is ahead.

The method im using attempts to solve this.
Instead of using a single point to measure distances, it has a vector between intersections of segments of the track. This is then projected forward to the furthest vertex at the other end of the segment, to give a reference within that segment, of distances to a point on that projection, defined by the intersection of a vector to the projection, the vector with the same direction as the direction of the segment. Let me draw a diagram.

Update.
I’m going for a slightly different method, getting the direction of the segment by the midpoint of the start vertices, and the midpoint of the end vertices, and using the vector between the two as the direction

Additionally:
Why can i not use sum() on a list of vectors?
Does it not use the built in operators?
Also, what is dot product - i’m learning about vectors as i go, so any help is really useful!

At a basic level, the dot product is used to obtain the cosine of the angle between two vectors.

It’s a really good idea to get your head around vectors since matrices are a natural expansion of vectors (a vector is a 1-dimensional matrix).

Just when you think you have vectors and matrices sorted feel free to go pop your head with quaternions. :smiley:

For summing a list of vectors, there’s no reason I can see that it’s not implemented. You could always write your own function…

Unchecked!


import mathutuils.Vector as Vector
vec1 = Vector[0,1,0]
vec2 = Vector[1,2,5]
vec3 = Vector[99.827, 428, 3.14159265359]

vecs = [vec1, vec2, vec3]

def sum_vecs(vecs):
    total_vec = Vector[0,0,0]
    for vec in vecs:
        total_vec += vec
    return total_vec

print(sum_vecs(vecs))

Here’s a modification of the calculation which accounts for the problem you mentioned.

pos = (i0 + (p1-p0).normalized().dot(pr - p0) / (p1-p0).length) / len(empties) + laps

The system is then, essentially, snapping the racer’s position to the closest point on a linearly-interpolated path defined by the empties.

I honestly don’t think there is a solution better than this, short of using a spline path, but the maths for that would become much more complex.