Angle() between angles?

Get help using Construct 2

» Sun Jun 03, 2012 1:59 pm

Hello everyone,

I have a quick question; I need to test if 3 points are collinear (with a bit of tolerance). So, what I am doing is finding the angle() between a base point and another point, and the base point and the last point. If these are within a certain range of each other, it needs to return true.
I tried to do this, but I can't find a way to test if the angle()s are within a range of each other. I used the 'is within range', which works most of the time, however it does NOT work when I encounter the +/- 180 gap given by the angle() expressions.

B
90
S
30
G
24
Posts: 3,189
Reputation: 32,390

» Sun Jun 03, 2012 2:33 pm

Angle() gives you the angle between two points, so if you are going beyond that try reversing the points.
B
160
S
48
G
80
Posts: 7,246
Reputation: 61,520

» Sun Jun 03, 2012 4:47 pm

@Newt, I am not going beyond that. I merely wish to compare two angle()s to see how close they are, but it gets hairy when I encounter the +/- 180 gap.
B
90
S
30
G
24
Posts: 3,189
Reputation: 32,390

» Sun Jun 03, 2012 5:25 pm

you could put your points in a family fpoint
and then
[code]Global alignement = 0
+[pick the three points you want to check with the object type point]
+[pick the three points you want to check with the family fpoint]
+system: pick point at random
local number a1 = 0 // angle between point and the first fpoint
local number a2 = 0 // angle between point and the second fpoint
+system: for each fpoint
+system: point.UID != fpoint.UID // don't pick itself
+loopindex = 0
->system: set a1 to angle(point.X,point.Y,fpoint.X,fpoint.Y)
+loopindex = 1
->system: set a2 to angle(point.X,point.Y,fpoint.X,fpoint.Y)
-> System: set alignement to min(1,abs(cos(a1)*cos(a2)+sin(a1)*sin(a2)))[/code]
Basically it should look at one of your 3 points and calculate the angle between the other two.
So if the point randomly picked is at one extremity, the angle between this point and the two others should be the same.
If the point randomly picked is the middle one, the angle should be opposite.

To compare alignement between two direction (or vectors) there's a neat operation called dot product.
If done on unit vectors (the ones with length = 1) you get a number from -1 to 1:
* 1 = aligned and pointing toward the same direction
* -1 = aligned and pointing toward opposite direction
* 0 = perpendicular
and between these values it would be a "percentage of alignement"

The formulat is:
given two vectors v1(x1,y1) and v2(x2,y2)
the dot product v1.v2 = x1*x2+y1*y2
If you have an angle 'a', the corresponding unit vector would be (cos(a),sin(a))
That's why cos(a1)*cos(a2)+sin(a1)*sin(a2) should give you the dot product.
the abs() is to have values from 0 to 1 that should give you a percentage of alignement.
you then just have to check if 'alignement' is greater than something lik 0.9 and you're done (:
Yann2012-06-03 17:28:28
B
60
S
22
G
14
Posts: 1,479
Reputation: 16,336

» Sun Jun 03, 2012 5:30 pm

Thanks a lot Yann! I'll see what I can do.
B
90
S
30
G
24
Posts: 3,189
Reputation: 32,390