ColinHolloway Posted February 28, 2012 Posted February 28, 2012 (edited) Hi All, I am reading and calculating Transformation Matrices to record the position of xref's and insert them into other drawings in the same world location. (Please note I am using (rtos [value] 2 30) in these cases to display as many decimal places as possible, and DIMZIN is set to 0.) When I select an xref that has a rotation of 90° using (nentsel) I get: ( (-215381.0 479012.0 0.0) ((2.22045e-016 1.0 0.0) (-1.0 2.22045e-016 0.0) (0.0 0.0 1.0) (264376.0 9584.72 -7475.59)) ()) If I expand on the first item on the first list of the matrix using (rtos (car (car (caddr (nentsel)))) 2 30) I get: "2.220446049250313E-16" In the transformation matrix, this value is the cos of the xref rotation angle. The insertion angle of this block can be read using (rtos (cdr (assoc 50 (entget (car (entsel))))) 2 30) which gives: "1.570796326794896" This matches the calculated value for 90° using (rtos (* pi (/ 90 180.0)) 2 30) which gives: "1.570796326794896" So as far as the angle goes, both methods match. Here’s where is goes wrong… If I calculate the cos of 90° using (rtos (cos (* pi (/ 90 180.0))) 2 30) I get: "6.123233995736766E-17", which doesn’t match "2.220446049250313E-16" Now I understand that the difference between these two numbers is very small, but when I convert each back to an angle using acos and converting to degrees I get: (rtos (* (/ (acos (car (car (caddr (nentsel))))) pi) 180.0) 2 30) gives: "89.99999999999998" (rtos (* (/ (acos (cos (* pi (/ 90 180.0)))) pi) 180.0) 2 30) gives: "90.00000000000000" I can code to round these values to a lower number of decimal places, but because I am comparing the matrices and not the calculated angle, I need to understand where this error is coming from and possibly find a solution. Does anyone have any input on this issue? Thanks in advance, Colin Holloway Edited February 28, 2012 by ColinHolloway Code tags Quote
MSasu Posted February 28, 2012 Posted February 28, 2012 You will get rounding issues in other programming languages also, not only in AutoLISP. What I can see as a solution to your comparison is to make a dedicated function that will compare the items of the matrixes one by one – use EQUAL for comparison with an appropriate precision factor. (equal 89.99999999999998 90.00000000000000 [color=blue]0.0000001[/color]) Regards, Mircea Quote
SLW210 Posted February 28, 2012 Posted February 28, 2012 Please read the CODE POSTING GUIDELINES! Quote
Lee Mac Posted February 28, 2012 Posted February 28, 2012 Colin, Numbers are stored to a limited degree of accuracy, specifically, AutoLISP 'Reals' are stored as 32-bit Doubles (on a 32-bit machine), which offer approx 15 d.p. precision; to store a mathematically accurate representation of, say, root 2 would require an infinite amount of memory. As a result of this accuracy limit, rounding errors will occur at every arithmetical operation, compounding over multiple operations. When writing programs involving manipulation of Doubles, always use the equal function (as msasu suggests) and include a tolerance when comparing two Doubles. More information: http://www.cadtutor.net/forum/showthread.php?64760-Checking-Line-Angles&p=442140&viewfull=1#post442140 http://www.cadtutor.net/forum/showthread.php?60050-Help-What-wrong-in-Fix-defun&p=407806&viewfull=1#post407806 Quote
ColinHolloway Posted February 28, 2012 Author Posted February 28, 2012 Original post edited to add Code tags Quote
ColinHolloway Posted February 28, 2012 Author Posted February 28, 2012 Hi All, Thanks for the quick responses with guidance and information. I will use the equal function with appropriate tolerance for my comparison of these matrices. Colin Quote
SLW210 Posted February 28, 2012 Posted February 28, 2012 Original post edited to add Code tags Thank you very much! Quote
Recommended Posts
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.