Find angle for two drawlines

khos

Member
Licensed User
Longtime User
Hi,

I am starting to try make a basic game (shooting cannons at each other) but want to figure out how to calculate the angle (e.g. 33%) between to two drawlines, that originate from the same point. e.g:
Canvas1.DrawLine(10dip, 200dip, 310dip, 200dip, Colors.Red, 1dip)
Canvas1.DrawLine(10dip, 200dip, 340dip, 100dip, Colors.Red, 1dip)


There are quite a few VB samples out there, e.g:
Public Function GetAngle(ByVal Ax As Single, ByVal Ay As _
Single, ByVal Bx As Single, ByVal By As Single, ByVal _
Cx As Single, ByVal Cy As Single) As Single
Dim side_a As Single
Dim side_b As Single
Dim side_c As Single

' Get the lengths of the triangle's sides.
side_a = Sqr((Bx - Cx) ^ 2 + (By - Cy) ^ 2)
side_b = Sqr((Ax - Cx) ^ 2 + (Ay - Cy) ^ 2)
side_c = Sqr((Ax - Bx) ^ 2 + (Ay - By) ^ 2)

' Calculate angle B between sides ab and bc.
GetAngle = Acos((side_b ^ 2 - side_a ^ 2 - side_c ^ 2) _
/ (-2 * side_a * side_c))
End Function

' Return the arccosine of X.
Function Acos(ByVal X As Single) As Single
Acos = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1)
End Function

I tried to convert to Basic4Android but not having much luck sofar, e.g:
Sub GetAngle(Ax As Double, Ay As Double, Bx As Double, By As Double, Cx As Double, Cy As Double) As Double
Dim side_a As Double
Dim side_b As Double
Dim side_c As Double

' Get the lengths of the triangle's sides.
side_a = Sqrt((Bx - Cx) * 2 + (By - Cy) * 2)
side_b = Sqrt((Ax - Cx) * 2 + (Ay - Cy) * 2)
side_c = Sqrt((Ax - Bx) * 2 + (Ay - By) * 2)

' Calculate angle B between sides ab and bc.
'^
GetAngle = ACos((side_b * 2 - side_a * 2 - side_c * 2) / (-2 * side_a * side_c))
End Sub

' Return the arccosine of X.
Sub ACos(X As Double) As Double
ACos = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1)
End Sub

I see this post: http://www.b4x.com/forum/basic4android-updates-questions/8547-trigonometric-circle.html

I am rubbish at maths, I wondered if anyone would be able to help me out to see if this is possible, how should the data types be converted from the VB sample? or can the demo that Klaus/Erel wrote in http://www.b4x.com/forum/basic4android-updates-questions/8547-trigonometric-circle.html be used?

Thanks for any help with this :)
 

eps

Expert
Licensed User
Longtime User
Draw it out on a piece of paper or Google game geometry mathematics.

Ideally a piece of graph paper should really help.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
What exactly do you want to do ?
What angle do you want to get and what do you want to do with it ?
B4X:
 how to calculate the angle (e.g. 33%) between to two drawlines
Sorry but this is not really and angle ?
Do you want to know the angle or the steepness ?
It's almost similar but not the same.
And what do you want to do with the angle between the two lines ?

Best regards.
 
Upvote 0

eps

Expert
Licensed User
Longtime User
Work out an algorithm...

Pythagoras' theorem is your friend...

So line1

You know 2 of the lengths and one of the angles (it's 90 degrees).

SOHCAHTOA

Tan of Opposite/Adjacent.

Angle = Tan-1 of 200/300 = 33 degrees (plus a bit)

Maybe this?

ATan2D (Y As Double, X As Double) As Double
Returns the angle measured with degrees.

Then perform it on the other one...

Angle = Tan-1 of 100 / 330 = 16 and a little bit...

Then take one away from the other... then you have the angle between the two..

Or where you expecting something else?

This is why I mentioned using a piece of paper, to see what you are defining..

When the nos. change, just plug in the new numbers... Ideally use a Procedure, so that you can just call the same code again and again..

HTH
 
Upvote 0

khos

Member
Licensed User
Longtime User
Apologies for perhaps not being very clear, I'm still learning/experimenting, to see if things are possible.

Say I have a clockface and the 1st line (1st point of this line x1,y1 always 0,0) is at 24:00 hours, the 2nd line can rotate 360 degrees all the way around (1st point of the 2nd line x2,y2 also always 0,0, I think), if I draw the 2nd line programatically (e.g. use drawstring to draw these lines) so the 2nd point on the 2nd line is somewhere (x4,y4), how can I work out the angle of the 2nd line is compared to the 1st line. The 1st line would never change, it is constant. The only values that would change are (x4,y4) on the 2nd line in my application.

I just used "e.g. 33%", I see now that is incorrect.. it should be degrees 0-360.
 
Upvote 0

eps

Expert
Licensed User
Longtime User
Apologies for perhaps not being very clear, I'm still learning/experimenting, to see if things are possible.

Say I have a clockface and the 1st line (1st point of this line x1,y1 always 0,0) is at 24:00 hours, the 2nd line can rotate 360 degrees all the way around (1st point of the 2nd line x2,y2 also always 0,0, I think), if I draw the 2nd line programatically (e.g. use drawstring to draw these lines) so the 2nd point on the 2nd line is somewhere (x4,y4), how can I work out the angle of the 2nd line is compared to the 1st line. The 1st line would never change, it is constant. The only values that would change are (x4,y4) on the 2nd line in my application.

I just used "e.g. 33%", I see now that is incorrect.. it should be degrees 0-360.

See my post above.... Go and google SOHCAHTOA you are interested in the TOA part... If you can't understand that, then I can't help you! Work out TOA for both and then take one away from the other, job done.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
You do not need to write a function for ACos since B4A already implements it.
Secondly, use ACosD if you want the angle in degrees and not radians.

Thirdly, eps, this is not necessarily a right angled triangle.

Fourthly, just use the cosine rule: Law of cosines - Wikipedia, the free encyclopedia

Your code is incorrect because instead of squaring you are multiplying by 2.
Try this:
B4X:
Sub GetAngle(Ax As Double, Ay As Double, Bx As Double, By As Double, Cx As Double, Cy As Double) As Double
Dim side_a As Double
Dim side_b As Double
Dim side_c As Double

' Get the lengths of the triangle's sides.
side_a = Sqrt(power(Bx - Cx,2) + power(By - Cy,2))
side_b = Sqrt(power(Ax - Cx,2) + power(Ay - Cy,2))
side_c = Sqrt(power(Ax - Bx,2) + power(Ay - By,2))

' Calculate angle B between sides ab and bc.
'^
GetAngle = ACosD((power(side_b,2) - power(side_a, 2) - power(side_c, 2) / (-2 * side_a * side_c))
End Sub

This should work for you provided you give the correct A,B,C vertices. The point (Bx,By) is the common point where both lines meet.
 
Upvote 0

eps

Expert
Licensed User
Longtime User
You do not need to write a function for ACos since B4A already implements it.
Secondly, use ACosD if you want the angle in degrees and not radians.

Thirdly, eps, this is not necessarily a right angled triangle.

Fourthly, just use the cosine rule: Law of cosines - Wikipedia, the free encyclopedia

Your code is incorrect because instead of squaring you are multiplying by 2.
Try this:
B4X:
Sub GetAngle(Ax As Double, Ay As Double, Bx As Double, By As Double, Cx As Double, Cy As Double) As Double
Dim side_a As Double
Dim side_b As Double
Dim side_c As Double

' Get the lengths of the triangle's sides.
side_a = Sqrt(power(Bx - Cx,2) + power(By - Cy,2))
side_b = Sqrt(power(Ax - Cx,2) + power(Ay - Cy,2))
side_c = Sqrt(power(Ax - Bx,2) + power(Ay - By,2))

' Calculate angle B between sides ab and bc.
'^
GetAngle = ACosD((power(side_b,2) - power(side_a, 2) - power(side_c, 2) / (-2 * side_a * side_c))
End Sub

This should work for you provided you give the correct A,B,C vertices. The point (Bx,By) is the common point where both lines meet.

The two triangles are right angled triangles, then subtract. The combination of the two are not right angled triangles. :)
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
The two triangles are right angled triangles, then subtract. The combination of the two are not right angled triangles. :)

You are correct. I couldnt see your diagram in my head ;)
You probably mean something like this?

Angle1 = ATan((y0 - y1)/(x0 - x1))
and
Angle2 = ATan((y0 - y2)/(x0 - x2))
and the angle between the lines will be
Angle = Angle2 - Angle1
 
Upvote 0

eps

Expert
Licensed User
Longtime User
You are correct. I couldnt see your diagram in my head ;)
You probably mean something like this?

Angle1 = ATan((y0 - y1)/(x0 - x1))
and
Angle2 = ATan((y0 - y2)/(x0 - x2))
and the angle between the lines will be
Angle = Angle2 - Angle1

Yep, that's the way I "saw" it :) With this sort of stuff there are many, many ways to "skin the cat..."

Whatever works for you! It may well be that polar stuff starts to play a part and this is too easily broken... etc...

:)

As long as the OP gets a solution that works for them, then they're sorted. I just drew out what was happening on paper + CAD software and then worked out how to get the figures involved, but it's been a long time since I've done any geometry stuff...
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Yep, that's the way I "saw" it :) With this sort of stuff there are many, many ways to "skin the cat..."

Whatever works for you! It may well be that polar stuff starts to play a part and this is too easily broken... etc...

:)

As long as the OP gets a solution that works for them, then they're sorted. I just drew out what was happening on paper + CAD software and then worked out how to get the figures involved, but it's been a long time since I've done any geometry stuff...

Somethings are easily broken with Tan.
For e.g. Tan(0) = Tan(180)
and Tan-1(Infinity) = 90
But you can code workarounds for those.

..but yes...there are many many ways to skin a cat in geometry ;)
 
Upvote 0

khos

Member
Licensed User
Longtime User
You do not need to write a function for ACos since B4A already implements it.
Secondly, use ACosD if you want the angle in degrees and not radians.

Thirdly, eps, this is not necessarily a right angled triangle.

Fourthly, just use the cosine rule: Law of cosines - Wikipedia, the free encyclopedia

Your code is incorrect because instead of squaring you are multiplying by 2.
Try this:
B4X:
Sub GetAngle(Ax As Double, Ay As Double, Bx As Double, By As Double, Cx As Double, Cy As Double) As Double
Dim side_a As Double
Dim side_b As Double
Dim side_c As Double

' Get the lengths of the triangle's sides.
side_a = Sqrt(power(Bx - Cx,2) + power(By - Cy,2))
side_b = Sqrt(power(Ax - Cx,2) + power(Ay - Cy,2))
side_c = Sqrt(power(Ax - Bx,2) + power(Ay - By,2))

' Calculate angle B between sides ab and bc.
'^
GetAngle = ACosD((power(side_b,2) - power(side_a, 2) - power(side_c, 2) / (-2 * side_a * side_c))
End Sub

This should work for you provided you give the correct A,B,C vertices. The point (Bx,By) is the common point where both lines meet.


Hi there,
GetAngle = ACosD((power(side_b,2) - power(side_a, 2) - power(side_c, 2) / (-2 * side_a * side_c))

Gives me:
Error description: Invalid number of parentheses.

Where are they missing?
 
Upvote 0
Top