Jump to content

Working with PI and Polar Coordinates


abraxus

Recommended Posts

I hate it... there's just something i'm not doing right

 

I define a global constant in my module:

 

Global Const pi = 3.14159265459

that should be enough significant digits, right?

 

I do some calculations and then compare values

 

Function AngleSimilar(pt1 As Variant, pt2 As Variant, blk As AcadBlockReference) As Boolean
 Dim dAngleRadians As Single
 Dim dBlockRadians As Single
 Dim dBlockRadians0 As Single
 Dim dBlockRadians90 As Single
 Dim dBlockRadians180 As Single
 Dim dBlockRadians270 As Single
 
 dAngleRadians = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
 dBlockRadians = blk.Rotation
 If dAngleRadians > pi * 2 Then dAngleRadians = dAngleRadians - (pi * 2)
 dBlockRadians0 = dBlockRadians
 If dBlockRadians0 > pi * 2 Then dBlockRadians0 = dBlockRadians0 - (pi * 2)
 dBlockRadians90 = dBlockRadians - pi * 0.5
 If dBlockRadians90 > pi * 2 Then dBlockRadians90 = dBlockRadians90 - (pi * 2)
 dBlockRadians180 = dBlockRadians - pi * 1
 If dBlockRadians180 > pi * 2 Then dBlockRadians180 = dBlockRadians180 - (pi * 2)
 dBlockRadians270 = dBlockRadians - pi * 1.5
 If dBlockRadians270 > pi * 2 Then dBlockRadians270 = dBlockRadians270 - (pi * 2)
 
 If dAngleRadians = dBlockRadians0 Or dAngleRadians = dBlockRadians90 Or dAngleRadians = dBlockRadians180 Or dAngleRadians = dBlockRadians270 Then
   AngleSimilar = True
 Else
   Debug.Print dAngleRadians, dBlockRadians0
   Debug.Print dAngleRadians, dBlockRadians90
   Debug.Print dAngleRadians, dBlockRadians180
   Debug.Print dAngleRadians, dBlockRadians270
 End If
 
End Function

as you can see in the DIMS, they are singles (they used to be doubles, i changed them to singles to see if it would fix my matching problem, that's why they start with a d... i was lazy... anyways

 

the reason i put some Debug.Print lines in there is because i couldnt believe things werent matching up as they should, one of the 4 points just HAD TO match

 

the Debug.Print proved that... as here is the result of debug.print

 

 2.356194      5.497787 
2.356194      3.926991 
2.356194      2.356194 
2.356194      0.785398 

but the "if" statement comparing the values still never was true in any of the 4 cases

 

so in the debug window while the code was stopped at a breakpoint, i typed this (expecting it to be true) and it wasnt

 

? dAngleRadians = dBlockRadians180

but it was false

 

so then i tried

? cstr(dAngleRadians) = cstr(dBlockRadians180)

and it was true - i converted the single value to a string... and now it's working...

 

i mean that's great, i got it working, but i shouldnt have to convert identical single values to strings in order to make them test true on a conditional statement.. any advice?

 

(and yes, i realize the code is a bit convoluted and could be written more efficiently, but because of the problems i was having, i wanted lots of easily debugged values to evaluate)

Edited by abraxus
Link to comment
Share on other sites

I think it advisable to stick with the native formats. As you see, the “Single” also has problems with direct comparison, and conversions (Double to Single, Single to String) have processing overhead.

 

Comparing Double for equality has the same issue in all programming languages: What seems like it should be equal is not always the case. See the example function below, it compares Double values.

 

 
Function Equal(dblVal1 As Double, dblVal2 As Double, Optional ByVal dblTol As Double = 0.0001) As Boolean
Equal = False
If Abs(dblVal1 - dblVal2 ) < dblTol Then
Equal = True
End If
End Function

 

On a side note, VBA’s Modulus function (MOD) may be useful for angle additions.

 

PS be careful of formatting issues in the code block above

Link to comment
Share on other sites

I can only iterate what Sean said and recommend his function. I only use the method of subtracting on value from another and seeing if its within a given tolerance. But don't forget to use the absolute value of the difference or you will get some false results.

 

I also define PI as 'PI = 4 * ATN(1)'. I find it easier to remember as the long numeric term. I've used it some very accurate calculations and never found the definition to yield false results.

Link to comment
Share on other sites

That is not a bad idea, SeanT - i will look into that - i was just frustrated last night as it was getting late, and converting it to a string worked, but yes, it did slow the process down a bit

 

could you explain what you mean by "VBA’s Modulus function (MOD)"? i am not familiar with that

 

thanks again

 

and tyke, i have never thought about calculating PI like that... (you just cant use it as a constant then, which isnt the end of the world if it fixes the problem)

 

i've had PI memorized to 10 digits since i was like 13 years old (i'm 44 now) - but i will consider your suggestion as well

Link to comment
Share on other sites

oh yeah, i still havent tried the eval function instead of converting to a string... i guess i will be doing that this weekend as well, that should speed up the iterations a bit

Link to comment
Share on other sites

Oops. I guess I lost track of this thread.

 

The modulus operator divides two numbers but only returns the partial remainder. So:

 

10 Mod 5 would return 0

 

But

 

10 Mod 3 would return 1

 

 

For Angles:

 

Global Const pi =3.14159265459

 

Global Const 2pi= pi * 2

 

Ang1 = pi/2 ’90 degrees

 

Ang2 = pi * 1.75 ‘315 degrees

 

AngAddition = (Ang1 + Ang2) Mod 2pi

 

AngAddition would be 45 degrees

Link to comment
Share on other sites

I would think the easiest way is to use the Math.PI constant. I would check this but I no longer use VBA. I stay with C# for the most part anymore.

Link to comment
Share on other sites

I have the "math" object, but it doesnt have a "pi" in it....

 

but this makes me wonder, there are SIN and COS and ATN and TAN methods in the Math object... are these slower or faster than the SIN() and COS() etc functions? i mean, it seems like duplicated effort, so there must be a difference, right?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...