Author Topic: Intersectwith help  (Read 2407 times)

0 Members and 1 Guest are viewing this topic.

CincyJeff

  • Newt
  • Posts: 89
Intersectwith help
« on: September 29, 2015, 07:46:13 AM »
I'm trying to draw a leader line from a detail callout symbol to a boundary polyline. I want the leader line to point to the center of the boundary and stop where it intersects the boundary. I've got some partial code that will draw a rectangular boundary, fillet the corners, calculate the center point, draw a line from the center point to a user selected point, and return the intersection point of the line and the boundary or nil. The code works fine if the second point makes the line go through a straight segment of the boundary polyline but typically fails to find the intersection point if the line goes through an arc segment. It seems to be hit-or-miss, but mostly miss. Is there a way to make vla-intersectwith consistently find the intersection point for a polyline arc segment?

Code - Auto/Visual Lisp: [Select]
  1. (defun C:IW (/ bndry cntrpt dist intarr intbnd intpt llpt pt1 pt2 pt3 pt4 scale tmpline urpt)
  2.   (setq scale (/ 1 (getvar "cannoscalevalue")))
  3.   (setq pt1 (getpoint "\nFirst corner: "))
  4.   (setq pt3 (getcorner pt1 "\nOther corner: "))
  5.   (if (and pt1 pt3)
  6.     (progn
  7.       (setq pt2 (list (car pt3) (cadr pt1)))
  8.       (setq pt4 (list (car pt1) (cadr pt3)))
  9.       (vl-cmdf "_.pline" pt1 pt2 pt3 pt4 "close")
  10.       (if (< (distance pt1 pt2) (distance pt1 pt4))
  11.         (setq dist (distance pt1 pt2))
  12.         (setq dist (distance pt1 pt4))
  13.       ) ;_ end of if
  14.       (if (> dist (* 0.25 scale))
  15.         (setvar "filletrad" (* 0.125 scale))
  16.         (setvar "filletrad" (/ dist 2.2))
  17.       ) ;_ end of if
  18.       (vl-cmdf "_.fillet" "polyline" (entlast))
  19.     ) ;_ end of progn
  20.   ) ;_ end of if
  21.   (if (not cntrpt)
  22.     (progn
  23.       (setq bndry (vlax-ename->vla-object (entlast)))
  24.       (vla-getboundingbox bndry 'x 'y)
  25.       (setq llpt (vlax-safearray->list x))
  26.       (setq urpt (vlax-safearray->list y))
  27.       (setq cntrpt (polar llpt (angle llpt urpt) (/ (distance llpt urpt) 2)))
  28.     ) ;_ end of progn
  29.   ) ;_ end of if
  30.   (vl-cmdf "_.line" cntrpt pause "")
  31.   (setq tmpline (entlast))
  32.   (setq intarr (vlax-variant-value
  33.                  (vla-intersectwith
  34.                    bndry
  35.                    (vlax-ename->vla-object tmpline)
  36.                    acextendnone
  37.                  ) ;_ end of vla-intersectwith
  38.                ) ;_ end of vlax-variant-value
  39.   ) ;_ end of setq
  40.   (setq intbnd (vlax-safearray-get-u-bound intarr 1))
  41.   (if (/= intbnd -1)
  42.     (progn
  43.       (setq intpt (vlax-safearray->list intarr))
  44.       (if (> intbnd 3)
  45.         (setq intpt (cdddr intpt))
  46.       ) ;_ end of if
  47.     ) ;_ end of progn
  48.   ) ;_ end of if
  49.   (princ intpt)
  50. ) ;_ end of defun
  51.  
  52. (prompt "\nType IW to run")

ymg

  • Guest
Re: Intersectwith help
« Reply #1 on: September 29, 2015, 09:50:17 AM »
Try with this:

Code - Auto/Visual Lisp: [Select]
  1. (defun C:IW (/ )
  2.    (setq scale (/ 1 (getvar "cannoscalevalue"))
  3.            pt1 (getpoint "\nFirst corner: ")
  4.            pt3 (getcorner pt1 "\nOther corner: ")
  5.    )
  6.    (if (and pt1 pt3)
  7.       (progn
  8.          (setq pt2 (list (car pt3) (cadr pt1))
  9.                pt4 (list (car pt1) (cadr pt3))
  10.               dist (min (distance pt1 pt2)(distance pt1 pt4))
  11.               cntr (polar pt1 (angle pt1 pt3) (* (distance pt1 pt3) 0.5))
  12.         )
  13.         (vl-cmdf "_.pline" pt1 pt2 pt3 pt4 "close")
  14.         (if (> dist (* 0.25 scale))
  15.            (setvar "filletrad" (* 0.125 scale))
  16.            (setvar "filletrad" (/ dist 2.2))
  17.         )
  18.         (vl-cmdf "_.fillet" "polyline" (entlast))
  19.         (setq bndry (vlax-ename->vla-object (entlast)))
  20.         (vl-cmdf "_.line" cntr pause "")
  21.         (setq objline (vlax-ename->vla-object (entlast)))
  22.         (setq intarr (vlax-variant-value
  23.                         (vla-intersectwith bndry objline acextendnone)
  24.                      )
  25.         )
  26.         (setq intbnd (vlax-safearray-get-u-bound intarr 1))
  27.         (if (/= intbnd -1)
  28.            (progn
  29.               (setq intpt (vlax-safearray->list intarr))
  30.               (if (> intbnd 3)
  31.                  (setq intpt (cdddr intpt))
  32.               )
  33.            )
  34.         )
  35.         (princ intpt)
  36.       )
  37.    )  
  38. )
  39.  
  40. (prompt "\nType IW to run")
  41.  

ymg

  • Guest
Re: Intersectwith help
« Reply #2 on: September 29, 2015, 10:30:34 AM »
You should consider adding some subroutine to your toolbox.

Here again your proggie but using some generic routine.

Code - Auto/Visual Lisp: [Select]
  1. (defun C:IW (/ bndry cntr dist objline pt1 pt2 pt3 pt4 scale)
  2.    (setq scale (/ 1 (getvar "cannoscalevalue"))
  3.            pt1 (getpoint "\nFirst corner: ")
  4.            pt3 (getcorner pt1 "\nOther corner: ")
  5.    )
  6.    (if (and pt1 pt3)
  7.       (progn
  8.          (setq pt2 (list (car pt3) (cadr pt1))
  9.                pt4 (list (car pt1) (cadr pt3))
  10.               dist (min (distance pt1 pt2)(distance pt1 pt4))
  11.               cntr (midpoint pt1 pt3)
  12.         )
  13.         (setq bndry (mk_lwp (list pt1 pt2 pt3 pt4 pt1)))
  14.         (if (> dist (* 0.25 scale))
  15.            (setvar "filletrad" (* 0.125 scale))
  16.            (setvar "filletrad" (/ dist 2.2))
  17.         )
  18.         (vl-cmdf "_.fillet" "polyline" (entlast))
  19.         (vl-cmdf "_.line" cntr pause "")
  20.         (setq objline (vlax-ename->vla-object (entlast)))
  21.         (princ (car (intersections bndry objline acextendnone)))
  22.        
  23.       )
  24.    )  
  25. )
  26.  
  27. ;;                                                                            ;
  28. ;; triplet, Separates a list into triplets of items.                          ;
  29. ;;                                                                            ;
  30.  
  31. (defun triplet (l)
  32.    (if l (cons (list (car l) (cadr l) (caddr l))(triplet (cdddr l))))
  33. )
  34.  
  35. ;;                                                                            ;
  36. ;; Return list of intersection(s) between two objects                         ;
  37. ;; obj1 - first VLA-Object                                                    ;
  38. ;; obj2 - second VLA-Object                                                   ;
  39. ;; mode - intersection mode (acExtendNone acExtendThisEntity                  ;
  40. ;;                                acExtendOtherEntity acExtendBoth)           ;
  41. ;; Requires triplet                                                           ;
  42. ;;                                                                            ;
  43.      
  44. (defun Intersections (obj1 obj2 mode)
  45.    (triplet (vlax-invoke obj1 'intersectwith obj2 acExtendNone))          
  46. )
  47.  
  48. ;;                                                                            ;
  49. ;; mk_lwp    by Alan J Thompson                                               ;
  50. ;;                                                                            ;
  51. ;; Argument: pl, A list of points (2d or 3d)                                  ;
  52. ;; Create an LWPolyline at Elevation 0, on Current Layer.                     ;
  53. ;; Return: Polyline Object                                                    ;
  54. ;;                                                                            ;
  55.  
  56. (defun mk_lwp (pl / cl)
  57.    (setq cl 0)
  58.    (if (equal (car pl) (last pl) 0.001)
  59.       (setq cl 1 pl (cdr pl))
  60.    )  
  61.    (vlax-ename->vla-object
  62.       (entmakex
  63.          (append (list '(0 . "LWPOLYLINE")
  64.                        '(100 . "AcDbEntity")
  65.                        '(100 . "AcDbPolyline")
  66.                         (cons 90 (length pl))
  67.                         (cons 70 cl)
  68.                  )
  69.                  (mapcar '(lambda (p) (cons 10 (trans (list (car p) (cadr p)) 1 0))) pl)
  70.          )
  71.       )
  72.    )
  73. )
  74.  
  75. ;;                                                                            ;
  76. ;; midpoint                                                                   ;
  77. ;;                                                                            ;
  78. ;; Returns The Midpoint Between Point a and Point b                           ;
  79. ;;     (About 18% faster than mapcar)                                         ;
  80.  
  81. (defun midpoint (a b) (polar a (angle a b) (* (distance a b) 0.5)))
  82.  
  83.  
  84. (prompt "\nType IW to run")
  85. (prompt "\nType IW to run")
  86.  
« Last Edit: September 29, 2015, 10:40:50 AM by ymg »

CincyJeff

  • Newt
  • Posts: 89
Re: Intersectwith help
« Reply #3 on: September 29, 2015, 12:38:04 PM »
ymg,
I'm at a loss. Your reply #1 didn't change much at all except how you calculate the center point. I'm using the bounding box because I will want the final program to work with irregularly shaped polylines. How can the calculation of the center point affect the vla-intersectwith function? The original code drew the line correctly so why wouldn't that entity produce a valid result? What am I missing?
Jeff

CincyJeff

  • Newt
  • Posts: 89
Re: Intersectwith help
« Reply #4 on: September 30, 2015, 08:03:06 AM »
Got it. It turns out that the vla-getboundingbox function was returning an infinitesimal z-value that prevented the vla-intersectwith function from returning a usable value. Thanks ymg for the code suggestions.