My apologies if I've misunderstood the term 'unit vector' or misapplied it in concept, but I think that is the term for an object's heading when expressed as
[x, y] when
y are a value between -1 and 1; so if an object were moving 'south' on a computer screen, it would have a unit vector of
Anyway, I've been using this concept to move my objects and rotate their images (when needed), but I think the math I'm using to determine the unit vector is... suboptimal.
def set_heading(self, goal): """Uses a 'goal' (x, y) to set the object's heading. Returns list of 0s and 1s for 'straight' headings. Diagonal headings are + and/or - math.sqrt(2)/2. """ vals = [a - b for a, b in zip(goal, self.pos)] self.heading = [i / abs(i) if i != 0 else 0 for i in vals] if 0 not in self.heading: self.heading = [i * (sqrt(2)/2) for i in self.heading]
(If you're not familiar with Python ternary syntax, the second line contains
i / abs(i) if i != 0 else 0 which is Python's way of saying
x if Condition else y as opposed to the usual
Condition? x : else y syntax in other languages. Basically I'm just trying to avoid dividing by zero!)
So as you can see, this method of doing this sort of 'locks' the object into eight directions; if a 0 is not present in the heading, the method assumes that we're traveling diagonally and so multiplies the values by
sqrt(2) / 2 to ensure that the object doesn't travel faster than it should when moving diagonally. In this way I can move the object by simply adding the result of the unit vector times its speed to its current x and y coordinates.
def move(self): """Moves the object by changing self.pos.""" self.pos = [a + (b * self.speed) for a, b in zip(self.pos, self.heading)]
I can't help but feel like the method for getting the unit vector (if that's what it's correctly called) is sophomoric. Especially since it is locked into eight directions - it's fine for the little project I'm working with currently, but I'm not sure of the right method for getting a more precise unit vector. What is the correct method for doing so - and is it more or less performant than the weirdness I have come up with independently?