Author Topic: intersection Point on Non co-Planar Lines  (Read 4430 times)

0 Members and 1 Guest are viewing this topic.

mailmaverick

  • Bull Frog
  • Posts: 495
intersection Point on Non co-Planar Lines
« on: January 05, 2014, 04:43:48 AM »
I have two lines in AUTOCAD :-

LINE1 : (0 0 0) to (100 0 0)

LINE2 : (10 -10 10) to (20 10 10)

Now these two lines are non coplanar.

But when I see these lines in plan, autocad gives the snap point with "Apparent Intersection"

How to find this point in LISP ?

The snap point must lie on LINE1 i.e. (10 0 0) and not on LINE2.


Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: intersection Point on Non co-Planar Lines
« Reply #1 on: January 05, 2014, 06:02:22 AM »
Since the apparent intersection is dependent upon the view direction, consider the following:
Code - Auto/Visual Lisp: [Select]
  1. (defun appint ( p1 p2 p3 p4 / p v )
  2.     (setq v (getvar 'viewdir))
  3.     (if (setq p
  4.             (apply 'inters
  5.                 (mapcar '(lambda ( x ) (LM:projectpointtoplane x '(0.0 0.0) v))
  6.                     (list p1 p2 p3 p4)
  7.                 )
  8.             )
  9.         )
  10.         (inters p (mapcar '+ p v) p1 p2 nil)
  11.     )
  12. )
  13.  
  14. ;; Project Point onto Plane  -  Lee Mac
  15. ;; Projects pt onto the plane defined by its origin and normal
  16.  
  17. (defun LM:ProjectPointToPlane ( pt org nm )
  18.     (setq pt  (trans pt  0 nm)
  19.           org (trans org 0 nm)
  20.     )
  21.     (trans (list (car pt) (cadr pt) (caddr org)) nm 0)
  22. )

And a program to test:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / l1 l2 pt )
  2.     (if
  3.         (and
  4.             (setq l1 (car (entsel "\nSelect 1st line: ")))
  5.             (= "LINE" (cdr (assoc 0 (setq l1 (entget l1)))))
  6.             (setq l2 (car (entsel "\nSelect 2nd line: ")))
  7.             (= "LINE" (cdr (assoc 0 (setq l2 (entget l2)))))
  8.         )
  9.         (if
  10.             (setq pt
  11.                 (appint
  12.                     (cdr (assoc 10 l1))
  13.                     (cdr (assoc 11 l1))
  14.                     (cdr (assoc 10 l2))
  15.                     (cdr (assoc 11 l2))
  16.                 )
  17.             )
  18.             (entmake (list '(0 . "POINT") (cons 10 pt)))
  19.             (princ "\nNo apparent intersection found.")
  20.         )
  21.         (princ "\nLine not selected.")
  22.     )
  23.     (princ)
  24. )

mailmaverick

  • Bull Frog
  • Posts: 495
Re: intersection Point on Non co-Planar Lines
« Reply #2 on: January 05, 2014, 06:36:51 AM »
Thanks a lot Lee.

Always delighted to be helped by you. !!!!

But what if each of the two lines are polylines with multiple vertices ?
« Last Edit: January 05, 2014, 06:43:33 AM by mailmaverick »

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: intersection Point on Non co-Planar Lines
« Reply #3 on: January 05, 2014, 06:43:42 AM »
You're welcome!  :-)

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: intersection Point on Non co-Planar Lines
« Reply #4 on: January 05, 2014, 06:44:37 AM »
But what if each of the two lines are polylines with multiple vertices?

You would need to test each segment pair combination.

mailmaverick

  • Bull Frog
  • Posts: 495
Re: intersection Point on Non co-Planar Lines
« Reply #5 on: January 05, 2014, 07:46:17 AM »
Ok I got it.

Thanks.!!!!

mailmaverick

  • Bull Frog
  • Posts: 495
Re: intersection Point on Non co-Planar Lines
« Reply #6 on: January 05, 2014, 03:27:34 PM »
Dear Lee and other veterans,

I have an AUTOCAD drawing which contains thousands of contours in "CONTOURLINES" layer. All the vertices of each contour line are equal to the elevation of that particular contour.

Also, there are many polylines (each depicting a drain) in "DRAIN" layer. Note that all the vertices of these polylines have same elevation.

I want to find out the profile of each drain polyline by its intersection with various contours.

Going by Lee's method in which for each segment of each drain, all the segments of each contour are processed and a new list of intersection points is created. I have accomplished this code but this code takes lot of time.
Number of calculations = (sum of total number of line segments in all contour polylines) x (sum of total number of line segments in all drain polylines)

I have found a QUICKPROFILE routine on internet (http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=113&lngWId=13) in which each of the contour polylines are first modified (by ENTMOD) to the elevation of the current "drain" polyline and then the intersection points are found (using (vlax-invoke-method 'IntersectWith")) and the elevation of contour polyline is reversed back.

This method works very fast as compared to Lee's method.

My both above methods are working fine but I want to ask why is the QUICKPROFILE method so fast as compared to Lee's code ?
« Last Edit: January 05, 2014, 03:30:41 PM by mailmaverick »

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: intersection Point on Non co-Planar Lines
« Reply #7 on: January 05, 2014, 03:51:14 PM »
  • I am not aware of how you have implemented my function for use with polylines, so it could very well be your implementation that is slow.
  • My function is determining the apparent intersection based on the active view direction, not simply setting the lines to the same elevation, therefore the codes are not comparable.

mailmaverick

  • Bull Frog
  • Posts: 495
Re: intersection Point on Non co-Planar Lines
« Reply #8 on: January 06, 2014, 04:51:48 AM »
Dear Lee,

My question basically is why vla-intersectwith is faster than finding intersections each segment wise.

I have used following code to achieve this :-

My Code :-
Code: [Select]

(defun listptintersectleemac ()
;;; Gets apparent intersection point by projecting line across a plane
;;; Credit : Lee Mac
  (setq listaxy nil)
  (setq viewdir (getvar 'viewdir))
  (setq hazvalue (caddr (vlax-curve-getStartPoint ha-object)))
  (setq curvas contourstest)
;;; Curvas and Contourstest is selection set of all contours
  (setq ncurvas (sslength curvas))
  (setq listaxy nil)
  (setq counter 0)
  (setq listpoly nil)
  (setq ent (entget (car ha)))
  (setq elv (cdr (assoc 38 ent)))
  (setq ghhh 0)
  (foreach rec ent
    (if (= (car rec) 10)
      (progn (setq pnt (cdr rec))
     (setq xd (vlax-curve-getdistatPoint ha-ename pnt))
     (setq
       listpoly (append listpoly
(list (list (car pnt) (cadr pnt) elv xd))
)
     )
      )
    )
  )
  (setq
    listpoly (vl-sort
       listpoly
       (function (lambda (e1 e2) (< (cadddr e1) (cadddr e2))))
     )
  )
;;; listpoly is list of all vertices of selected drain polyline.
  (setq lenpoly (length listpoly))
  (while (< counter ncurvas)
    (progn
      (setq cnivel-ename (ssname curvas counter))
      (setq cnivel-object (vlax-ename->vla-object cnivel-ename))
      (setq cnivelzvalue
     (caddr (vlax-curve-getStartPoint cnivel-object))
      )
      (setq listcurr nil)
;;; listcurr is list of all vertices of current contour polyline.
      (setq ent (entget cnivel-ename))
      (setq elv (cdr (assoc 38 ent)))
      (foreach rec ent
(if (= (car rec) 10)
  (progn (setq pnt (cdr rec))
(setq xd (vlax-curve-getdistatPoint cnivel-object pnt))
(setq listcurr
(append listcurr
(list (list (car pnt) (cadr pnt) elv xd))
)
)
  )
)
      )
      (setq listcurr
     (vl-sort
       listcurr
       (function (lambda (e1 e2) (< (cadddr e1) (cadddr e2)))
       )
     )
      )
      (setq lencurr (length listcurr))
      (setq cntcurr 0)
      (repeat (- lencurr 1)
(setq p3 (nth cntcurr listcurr))
(setq p4 (nth (+ cntcurr 1) listcurr))
(setq p3 (list (car p3) (cadr p3) (caddr p3)))
(setq p4 (list (car p4) (cadr p4) (caddr p4)))
(setq cntpoly 0)
(repeat (- lenpoly 1)
  (setq p1 (nth cntpoly listpoly))
  (setq p1 (list (car p1) (cadr p1) (caddr p1)))
  (setq p2 (nth (+ cntpoly 1) listpoly))
  (setq p2 (list (car p2) (cadr p2) (caddr p2)))
;;; appint is Lee-Mac's function
  (if (setq pt (appint p1 p2 p3 p4 viewdir))
    (progn (setq ghhh (1+ ghhh))
   (setq xd (vlax-curve-getdistatPoint ha-ename pt))
   (setq
     listaxy (append listaxy (list (list xd (caddr p3))))
   )
    )
  )
  (setq cntpoly (1+ cntpoly))
)
(setq cntcurr (1+ cntcurr))
      )
    )
    (setq counter (1+ counter))
  )
)

(defun appint (p1 p2 p3 p4 v / p)
  (if (setq p
     (apply
       'inters
       (mapcar '(lambda (x) (LM:projectpointtoplane x '(0.0 0.0) v))
       (list p1 p2 p3 p4)
       )
     )
      )
    (inters p (mapcar '+ p v) p1 p2 nil)
  )
)

;;; Project Point onto Plane  -  Lee Mac
;;; Projects pt onto the plane defined by its origin and normal
(defun LM:ProjectPointToPlane (pt org nm)
  (setq pt  (trans pt 0 nm)
org (trans org 0 nm)
  )
  (trans (list (car pt) (cadr pt) (caddr org)) nm 0)
)

But in the code as per link given in my earlier post, it modifies the elevation of contour polyline, finds intersection point using vla-intersectwith and then revers the elevation back.

Lee Mac has also given a code in the following link in which he has modified the elevation of the contour and then reverted it back :-
http://www.cadtutor.net/forum/showthread.php?62153-data-from-contour&p=423779&viewfull=1#post423779

So my question is, Is this the only fastest way ? Can it be done without temporarily modifying the elevation of contour lines.
« Last Edit: January 06, 2014, 01:32:48 PM by mailmaverick »