Jump to content

Recommended Posts

Posted (edited)

Ok, I find some of the weirdest errors.

 

Background:

 

I am trying to find if 2 rectangles intersect, and if they do on more then 1 given point (IE corners are only touching) it will add it to the Rectangle Intersection list.

 

        (if (and(and (<= (min ax1 ax2) bx1) (>= (max ax1 ax2) bx1))(and (<= (min ay1 ay2) by1) (>= (max ay1 ay2) by1)))(setq int 1))
       (if (and(and (<= (min ax1 ax2) bx1) (>= (max ax1 ax2) bx1))(and (<= (min ay1 ay2) by2) (>= (max ay1 ay2) by2)))(setq int 1))
       (if (and(and (<= (min ax1 ax2) bx2) (>= (max ax1 ax2) bx2))(and (<= (min ay1 ay2) by1) (>= (max ay1 ay2) by1)))(setq int 1))
       (if (and(and (<= (min ax1 ax2) bx2) (>= (max ax1 ax2) bx2))(and (<= (min ay1 ay2) by2) (>= (max ay1 ay2) by2)))(setq int 1))

Yes, I know I should use cond but cond doesnt allow for more then 1 check, which I need.

 

Ok, Now the setup and the error.

 

Setup:

(setq acomp (nth 12 wlist))
   (setq aname (nth 0 acomp))
   (setq ax1 (nth 1 acomp))
   (setq ay1 (nth 2 acomp))
   (setq ax2 (nth 3 acomp))
   (setq ay2 (nth 4 acomp))
   (setq adir (nth 7 acomp))


(setq bcomp (nth 9 wlist))
     (setq bname (nth 0 bcomp))
     (setq bx1 (nth 1 bcomp))
     (setq by1 (nth 2 bcomp))
     (setq bx2 (nth 3 bcomp))
     (setq by2 (nth 4 bcomp))
     (setq bdir (nth 7 bcomp))
("P3" 202.0 175.0 226.0 178.0 202.0 176.5 "X")
"P3"
202.0
175.0
226.0
178.0
"X"
("W10" 198.0 142.0 202.0 254.0 200.0 142.0 "Y")
"W10"
198.0
142.0
202.0
254.0
"Y"

Error:

_$ ax1
202.0
_$ ax2
226.0
_$ bx2
202.0
_$ (min ax1 ax2)
202.0
_$ (<= (min ax1 ax2) bx2)
nil

 

Now, I went as far as to use Rtos, it kind of worked, but made my coding really ugly. So, I want to stay way from that.

 

Also, I used a tolerance and it "work" but it was tossing up false intersections at that point. So, I am thinking that for whatever reason AutoCAD is not using 100% accurate Snap points. Example: Click on a snap twice first time gives you 1.000000002 and the second time gives you 1.000000003. With that said I tried to look up some stuff on rounding real numbers but I couldn’t find anything or at least that is not blocked by my shop.

 

Any help you guys can provide would be great and much appreciated.

 

If you would like I can post an example that does work.

Edited by CADWarrior
Poor English. Revised for clarity.
Posted

AutoCAD has been known, at least in my experience, to indeed not be 100% accurate with its numbers. There are rounding errors and significant digit errors (maybe one in the same?), for example:

 

Command: (= pi 3.1415926535897932)
T
Command: (= pi 3.1415926535897933)
T

 

Your best bet is probably to introduce a "fuzz" factor in your calculations, which you can do with the "equal" function.

 

And if you're looking to clean up your code, try wrapping all the (and ...) functions into a single (and ...) function, or perhaps an (or ...). That way, every one will be evaluated without the need to have a bunch of if's. Another good tip for this sort of thing; if you have a lot of very similar if's, consider turning them into a loop of some kind; you might be able to save some space and clean it up.

 

Hope this helps, at least a bit!

Posted

The equations comes out to

_$ (Equal (min ax1 ax2) bx2 0.00000001)
T

But again this brings up False rectangular intersection.

Also, I used a tolerance and it "worked" but it was tossing up false intersections at that point.

Thanks for teaching me a new command though.

 

Is there a way to Round to the nearst 1/64" or 1/32". This would stop the false rectangle intersections by converting the intersection to the intended value.

 

Also, Here is a some revised code for clarity. And a better understanding of what I am trying to do.

 

    (setq int 0)

    (if
      (and
          (and (<= (min ax1 ax2) bx1)
               (>= (max ax1 ax2) bx1)
          );;point 1's x is between or on Rectangle 
          (and (<= (min ay1 ay2) by1)
               (>= (max ay1 ay2) by1)
          );;point 1's y is between or on Rectangle 
       );;point 1 is between or on Rectangle 
     (setq int (+ int 1));; Rectangles intersect add to intesections
     );;end if

    (if
      (and
          (and (<= (min ax1 ax2) bx1)
               (>= (max ax1 ax2) bx1)
           );;point 2's x is between or on Rectangle 
          (and (<= (min ay1 ay2) by2)
               (>= (max ay1 ay2) by2)
          );;point 2's y is between or on Rectangle
      );;point 2 is in or on Rectangle
      (setq int (+ int 1));; Rectangles intersect add to intesections
      );;end if

    (if
      (and
          (and (<= (min ax1 ax2) bx2)
               (>= (max ax1 ax2) bx2)
           );;point 3's x is between or on Rectangle 
          (and (< (min ay1 ay2) by1)
              (> (max ay1 ay2) by1)
          );;point 3's y is between or on Rectangle
        );;point 3 is in or on Rectangle
      (setq int (+ int 1));; Rectangles intersect add to intesections
      );;end if

    (if
      (and
          (and (<= (min ax1 ax2) bx2)
               (>= (max ax1 ax2) bx2)
          );;point 4's x is between or on Rectangle 
          (and (<= (min ay1 ay2) by2)
               (>= (max ay1 ay2) by2)
          );;point 4's y is between or on Rectangle
       );;point 4 is in or on Rectangle
      (setq int (+ int 1));; Rectangles intersect add to intesections
      );;end if

Posted (edited)

Ok All fixed

 

Thank you for the help freerefill.

 

Round Function:

(defun round (number xth / ro x y out)
   (if (> xth 0)
     (progn
(setq ro (rem number 1))
(setq x (- number ro))
(if (>= (rem (* (expt 10 xth) ro) 1) 0.5) (setq add 1) (setq add 0))
(setq y (/(- (* (expt 10 xth) ro) (- (rem (* (expt 10 xth) ro) 1) add)) (expt 10 xth)))
(setq out (+ x y))
)
     )
   (if (= xth 0)
     (progn
(setq ro (rem number 1))
(setq out (- number ro))
)
     )
   (if (< xth 0)
     (progn
(setq xth (* xth -1))
(setq ro (rem (/ number (expt 10 xth)) 1))
(setq out (* (- (/ number (expt 10 xth)) ro)(expt 10 xth)))
)
     )
   out
   )

 

Rectangle Check:


    (setq int 0)
    (if(and(and(<= (min ax1 ax2) bx1)(>= (max ax1 ax2) bx1))(and (<= (min ay1 ay2) by1)(>= (max ay1 ay2) by1)))(setq int (+ int 1)))
    (if(and(and(<= (min ax1 ax2) bx1)(>= (max ax1 ax2) bx1))(and (<= (min ay1 ay2) by2)(>= (max ay1 ay2) by2)))(setq int (+ int 1)))
    (if(and(and(<= (min ax1 ax2) bx2)(>= (max ax1 ax2) bx2))(and (<= (min ay1 ay2) by1)(>= (max ay1 ay2) by1)))(setq int (+ int 1)))
    (if(and(and(<= (min ax1 ax2) bx2)(>= (max ax1 ax2) bx2))(and (<= (min ay1 ay2) by2)(>= (max ay1 ay2) by2)))(setq int (+ int 1)))
    (if (> int 1) (progn))

 

 

Input:

_$ (setq acomp (nth 1 wlist))
   (setq aname (nth 0 acomp))
   (setq ax1 (round (nth 1 acomp) 4))
   (setq ay1 (round (nth 2 acomp) 4))
   (setq ax2 (round (nth 3 acomp) 4))
   (setq ay2 (round (nth 4 acomp) 4))
   (setq adir (nth 7 acomp))

(setq bcomp (nth 0 wlist))
     (setq bname (nth 0 bcomp))
     (setq bx1 (round (nth 1 bcomp) 4))
     (setq by1 (round (nth 2 bcomp) 4))
     (setq bx2 (round (nth 3 bcomp) 4))
     (setq by2 (round (nth 4 bcomp) 4))
     (setq bdir (nth 7 bcomp))
("W2" 326.0 6.0 330.0 138.0 328.0 6.0 "Y")
"W2"
326.0
6.0
330.0
138.0
"Y"
("W1" 22.0 6.0 326.0 10.0 22.0 8.0 "X")
"W1"
22.0
6.0
326.0
10.0
"X"

 

Output:

0
nil
nil
1
2

Edited by CADWarrior
Working Code
Posted

A is_point_in_box test can be condensed quite a bit

 

 

[color=#8b4513];;;ARG -> Test_pt Corner_Pt1 Corner_Pt2[/color]
[color=#8b4513];;;RET -> T nil[/color]
[b][color=BLACK]([/color][/b]defun is_pt_in_box [b][color=FUCHSIA]([/color][/b]tp p1 p2 / x1 x2 y1 y2[b][color=FUCHSIA])[/color][/b]
  [b][color=FUCHSIA]([/color][/b]setq x1 [b][color=NAVY]([/color][/b]car p1[b][color=NAVY])[/color][/b]  x2 [b][color=NAVY]([/color][/b]car p2[b][color=NAVY])[/color][/b]
        y1 [b][color=NAVY]([/color][/b]cadr p1[b][color=NAVY])[/color][/b] y2 [b][color=NAVY]([/color][/b]cadr p2[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]
  [b][color=FUCHSIA]([/color][/b]and [b][color=NAVY]([/color][/b]>= [b][color=MAROON]([/color][/b]max x1 x2[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]car tp[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]min x1 x2[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b]
       [b][color=NAVY]([/color][/b]>= [b][color=MAROON]([/color][/b]max y1 y2[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]cadr tp[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]min y1 y2[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b]

 

 

-David

Posted

The 'round' function could also be condensed immensely:

 

;; x  - number to be rounded
;; p  - decimal place to round to
(defun _round ( x p / e )
 (/ (fix (+ (* x (setq e (expt 10. p))) (/ x (abs x) 2.))) e)
)

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...