We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I want to calculate values based on the change in direction. If it keeps going the same it should be 1. If it goes back (so 180 degrees change) then it should be 0. And then everything in-between.
As last, the calculations should be fast! I tried some things with the cross and dot product but not sure if that is the right way to go.
Hope someone can help.
Here some code to get started, with my attempts removed.
PVector a, b, c;
void setup() {
size(600, 600);
a = new PVector(50, 50);
b = new PVector(width/2, height/2);
c = new PVector();
}
void draw() {
c.set(mouseX, mouseY);
background(0);
beginShape();
stroke(255);
noFill();
vertex(a.x, a.y);
vertex(b.x, b.y);
vertex(c.x, c.y);
endShape();
// magic...
}
Answers
The PVector class has a heading() function that would come in handy.
Maybe try creating two "heading vectors" made up of the difference between your connected vectors. Then just take the difference of those vector's heading() values and divide by the max.
code for heading in case interested.
I got it, when trying to play with the heading I discovered I did something wrong before.
Here code for dot product to show it's cheap:
Wouldn't returning
-angle
be more direct than multiplying by-1
? :-?Even better, a more succinct 1-line
return
: :ar!FYI the dot product of 2 vectors gives the cosine of the angle between. Which is -1 for 180° and +1 for 0°. So adding 1 and dividing by 2 gives the range you want.
@GoToLoop the code for the heading I posted is straight from Processing PVector.
@quark I figured about the adding 1 and dividing by 2 as I had in my last post. However, the values are wrong.
First, I figured that I wanted the values the other way around. So if a line keeps going in the same direction it should be 0. If the line goes back it should be 1.
What I have now looks ok if the angle is 0, 90, 180, 270 or 360. But with a 45 angle the value makes no sense. I only have no clue why. I found it really hard to think in vector math.
Can someone please explain why a 45 angle isn't in steps of 0.25?
Processing uses the standard of measuring angles in units of radians. There are 2*PI radians in a circle, so 180 degrees is PI radians, 90 degrees is PI/2 radians, and 45 degrees is PI/4 radians.
Processing provides the useful constants of TWO_PI, PI, HALF_PI, and QUARTER_PI.
thx, but this is about the dot product, not radians. And If i look straight left, up, right then the values are 0.0, 0.5 and 1.0 like expected, but in between it makes no sense.
i'm sure we've seen this question before which makes me think this is an assignment.
a.b is defined as |a| * |b| * cos(angle). i think it's the cos that's causing the non-linear values. maybe throw an acos and a map in there...
maths!
turns out that acos(b.dot(a)) = angleBetween(a, b)
https://processing.org/reference/PVector_angleBetween_.html
Sorry. That's what I get for not reading the whole thread.
I'm graduated so no assignments from me :D Thanks. The acos does it. Although I really hoped it was possible in a more simple matter (as in less cpu cycles).
if you use angleBetween you don't need the normalise calls beforehand.
a quick and dirty test of half a million calls gave the following results
(that's in seconds, so about one second for a million of your loops. is that fast enough?)
ok, new method using atan2
no normalise, no dot, two calls to atan2 and some finagling of the value, less than half the time
Who koogs that is really cool :) I use this for a pathfinder that looks at the angle of corners, I have to use this a lot more then a million times so this makes me happy :D
There is a bug in your code. If I change a to:
a = new PVector(width-50, height/2);
Then I get values exceeding the 1 range.
just dropping as a reference (for myself)
only one? 8)
yeah, i did only test it with the original line and did wonder if another starting line would break it. the problem is that atan2 returns values from -PI to PI so adding them or subtracting them gives a possible range (or do i mean domain) of two whole circles.
will have a play with it tonight, see what i can do.
cool :)
O yeah it kinda sucks I can't undo a "accept answer".
ok, i think you can probably reduce the dot4 calculation... probably.
It's not a big deal for me to use the slower version :) But I appreciate what you are doing.
Current one looks quite ok. I only have a NaN in red text when it points to the top left corner. However, i'm to tired to read code :)
hadn't noticed the NaN, i wonder why that is...
luckily, the red text is the old dot product version, the new one is in blue.
@koogs, acos expects values in the range -1 to 1. Due to rounding errors the value is sometimes -1.0000001, producing the NaN.