Jump to content

Create line base on angled lines. (non VL would be great).


Sheep

Recommended Posts

14 hours ago, Sheep said:

 

As far as I can see, you need to draw , what we call here OCHAVA , chamfer,   for parcel at city blocks corner. 

Is it so?

 

 

Link to comment
Share on other sites

Agree with you.

 

Forgot to get angle in code method posted do easy way using dim angle and get the angle. Then erase dim. 

 

Dim ang use pt1 line1

pt2  line2

pt3  mid pt1-pt2 

get dimension value then erase.

Edited by BIGAL
Link to comment
Share on other sites

As my LISP is so far from gurus LISP , and as I take this post to learn by myself .

 

I try to do what  I think it can be do by no VL- functions . Following the xline offset way as  suggested. 

 

I'm  struggled trying to make a line over the xline , so then do the offset  such line and get INTERS from the offsets 'd lines  to the original lines .

 

 

Please see the attached dwg and my RUDE lisp. 

 

Apologize me. 

 

My English is not better than my lisp. 

 

 

 

 

 

BLOCKS CHAMFERS.dwg TRY TO DO CHAMFER.lsp

  • Thanks 1
Link to comment
Share on other sites

I would like , at last , how to make a line over a XLINE.

 

Of course that math calc is other way.

 

I do all it as an intellectual exercise . 

 

Thanks 

 

 

 

Link to comment
Share on other sites

Devitg PM you a solution.

 

Would like Sheep to have a go with what I provided already. Happy to provide further advice.

 

For Jonathan the code is 43 lines long. Added to my library. 1/2 the code is the library function check ends. I cheated on the angle used dimang to get value and use "command" less lines than entmake, speed is not an issue, as only two objects get drawn. Need to add layer etc no error checking. 

 

image.png.53a2b4914f73d7df0697ef4dc1807621.png

 

I apolagise used a VL get dim angle will replace with entget so no VL 

Edited by BIGAL
Link to comment
Share on other sites

1 hour ago, BIGAL said:

Would like Sheep to have a go with what I provided already. Happy to provide further advice.

I'm working on it. I think i can see a clear solution from you. Give me some time to study this, i'm away from my state right now for several days. Thank you @BIGAL, @devitg, @Jonathan Handojo.

Link to comment
Share on other sites

2 hours ago, devitg said:

I'm  struggled trying to make a line over the xline , so then do the offset  such line and get INTERS from the offsets 'd lines  to the original lines

You don't have to draw an XLINE to find the intersection to the original lines. The inters function can actually accept an optional 5th argument: (inters p1 p2 p3 p4 [mode]). If you supply an argument to it (be it nil or any value), inters will find an intersection point assuming that the line formed by p1-p2 and p3-p4 is extended infinitely.

 

(inters
    '(0 1 0) '(0 2 0)
    '(1 0 0) '(2 0 0)
    nil
    )

 

  • Like 1
Link to comment
Share on other sites

Here's my non-VL method by pure maths:

(defun c:chf ( / dis getline ins len ln1 ln2 p1 p11 p12 p2 p21 p22)
    (defun getline (msg / ln)
	(while
	    (progn
		(setvar 'errno 0)
		(setq ln (car (entsel msg)))
		(cond
		    ((= (getvar 'errno) 7) (princ "\nNothing selected"))
		    ((null ln) nil)
		    ((not (eq (cdr (assoc 0 (entget ln))) "LINE")) (princ "\nObject is not a line"))
		    )
		)
	    )
	ln
	)
    
    (setq ln1 (getline "\nSelect first line: ")
	  ln2 (getline "\nSelect second line: ")
	  dis (getdist "\nSpecify line length: ")
	  p11 (cdr (assoc 10 (entget ln1)))
	  p12 (cdr (assoc 11 (entget ln1)))
	  p21 (cdr (assoc 10 (entget ln2)))
	  p22 (cdr (assoc 11 (entget ln2)))
	  ins (inters p11 p12 p21 p22 nil)
	  )
    (if ins
	(mapcar
	    '(lambda (x y / len p1 p2)
		 (if
		     (and
			 (not (equal x ins 1e-8))
			 (not (equal y ins 1e-8))
			 )
		     (progn
			 (setq len (/ dis (sqrt (* 2 (- 1 (cos (JH:InnerAngle x ins y))))))	; <-- cosine rule
			       p1 (polar ins (angle ins x) len)
			       p2 (polar ins (angle ins y) len)
			       )
			 (entmake (list '(0 . "LINE") (cons 10 p1) (cons 11 p2)))
			 )
		     )
		 )
	    (list p11 p12 p11 p12)
	    (list p21 p22 p22 p21)
	    )
	)
    
    (princ)
    )

;; JH:InnerAngle --> Jonathan Handojo
;; Returns the smaller angle between three point p1 p2 p3
;; with p2 as the pivot, in radians.

(defun JH:InnerAngle (p1 p2 p3 / 2p ang)
    (setq ang (- (angle p2 p3) (angle p2 p1)) 2p (+ pi pi))
    (while (not (<= 0 ang 2p)) (if (< ang 0) (setq ang (+ ang 2p)) (setq ang (- ang 2p))))
    (if (> ang pi) (- 2p ang) ang)
    )

 

Edited by Jonathan Handojo
  • Thanks 1
Link to comment
Share on other sites

@Jonathan Handojo, furthermore the geometric or math calc can be used . 

 

I want to know how to make a line OVER a any  XLINE ,  as I can will use in a future task , or just "because it like me." or "PER CHE ME PIACCE"

 

There is any way to do it by plain LISP? , by VL it can be do so

 

(COMMAND "xline" "B" ENT1-X-ENT2 ANG-PT1 ANG-PT2 "")

  (SETQ BISECT (ENTLAST))
(SETQ BISECT-DATA (ENTGET BISECT))
  
  (setq bisect-obj (vlax-ename->vla-object bisect))

(setq bisect-base-pt (vla-get-BasePoint bisect-obj))

(setq bisect-second-pt (vla-get-SecondPoint bisect-obj))

 (setq bisect-obj-base-xyz (safearray-value  (variant-value bisect-base-pt)))
;;;  (4408.92 1595.02 0.0) 

 (setq bisect-obj-second-xyz (safearray-value  (variant-value bisect-second-pt)))
  ;(4409.24 1595.97 0.0)

  (setq point-dist (distance bisect-obj-second-xyz bisect-obj-base-xyz))
(setq x-line-angle ( angle bisect-obj-second-xyz bisect-obj-base-xyz))

(command "line" bisect-obj-second-xyz bisect-obj-base-xyz "")
  (setq line/xline (entlast))
  (setq line/xline-mid 
  (command "erase" BISECT "")

 

Link to comment
Share on other sites

1 hour ago, devitg said:

@Jonathan Handojo, furthermore the geometric or math calc can be used . 

 

I want to know how to make a line OVER a any  XLINE ,  as I can will use in a future task , or just "because it like me." or "PER CHE ME PIACCE"

 

There is any way to do it by plain LISP? , by VL it can be do so

 


(COMMAND "xline" "B" ENT1-X-ENT2 ANG-PT1 ANG-PT2 "")

  (SETQ BISECT (ENTLAST))
(SETQ BISECT-DATA (ENTGET BISECT))
  
  (setq bisect-obj (vlax-ename->vla-object bisect))

(setq bisect-base-pt (vla-get-BasePoint bisect-obj))

(setq bisect-second-pt (vla-get-SecondPoint bisect-obj))

 (setq bisect-obj-base-xyz (safearray-value  (variant-value bisect-base-pt)))
;;;  (4408.92 1595.02 0.0) 

 (setq bisect-obj-second-xyz (safearray-value  (variant-value bisect-second-pt)))
  ;(4409.24 1595.97 0.0)

  (setq point-dist (distance bisect-obj-second-xyz bisect-obj-base-xyz))
(setq x-line-angle ( angle bisect-obj-second-xyz bisect-obj-base-xyz))

(command "line" bisect-obj-second-xyz bisect-obj-base-xyz "")
  (setq line/xline (entlast))
  (setq line/xline-mid 
  (command "erase" BISECT "")

 

Entget the xline. dxf code 10 is the initial selection point and code 11 a direction vector so

 

(setq elst (entget xl_ent))

(setq spt (cdr (assoc 10 elst))) ;initial picked point now start of line

(setq v (cdr (assoc 11 elst))); direction vector

(setq ept (mapcar '+ spt v);endpoint of line

(setq new_ent (entmakex (list '(0 . "LINE") (cons 10 spt) (cons 11 ept))))

 

once you have the line you can get the mid point (mapcar '(lambda (x y) (/ (+ x y) 2.0)) spt ept) and the angle of the line and use that to extend the line by however far you want by calculating the new start and end points from the middle using polar from the  midpoint

 

 

 

Link to comment
Share on other sites

So,  it is the trick

I have to understand about VECTOR. 

Thanks for it 

(setq ept (mapcar '+ spt v);endpoint of line

And to extend it I use scale base at  mid pont factor 

(command "scale" line/xline "" line/xline-mid 100)

to avoid further calcs 

 

Link to comment
Share on other sites

To be more specific, the direction vector is the difference in x y & z coords of a point 1 unit away from the initial point in the selected direction.

  • Like 1
Link to comment
Share on other sites

For sheep here is the formula for the length along the lines. Then use polar to work out the 2 points much easier than using xlines. Your on the right path with your code. 

 

(setq d2 (* (/ 1.0 (cos (- (/ pi 2.0) (/ ang 2.0)))) (/ dist 2.0)))
; d2 is dist along line
; ang is internal angle
; dist is chord length

here is the get internal angle

 

(command "dimangular" pt4 pt1 pt3)
(setq ang (cdr (assoc 42 (entget (entlast)))))
; pt4 is end line1
; pt1 is end line2
; pt3 is mid point pt1 - pt4

(setq pt3  (mapcar '+ pt1 pt4) )
(setq pt3 (mapcar '(lambda (x) (/ x 2.0)) pt3))

Working on a better method of picking lines  and getting direction away from intersection point, thanks Jonathon.

 

Edited by BIGAL
  • Like 1
Link to comment
Share on other sites

This is my 1st version need to improve the angle check. A quick cheat for polylines is if you do "explode" you can repick via code the line that now exists work out the new point then do a "Undo" so pline is returned lisp will remember the point.

 

; Do a chamfer on two lines given chord length
; By Alan H Aug 2020

(defun AH:getend ( / tp1 tpp1 d2 d1)
(setq tp1 (entsel "\nSelect line near end : "))
	(setq tpp1 (entget (car tp1)))
	(setq pt1 (cdr (assoc 10 tpp1)))
	(setq pt1 (list (car pt1) (cadr pt1) 0.0)) ;reset z to zero
	(setq pt2 (cdr (assoc 11 tpp1)))      
	(setq pt2 (list (car pt2) (cadr pt2) 0.0)) ;reset z to zero

	(setq pt3 (cadr tp1))
	
	(setq d1 (distance pt1 pt3))
	(setq d2 (distance pt2 pt3))
		(if (> d1 d2)
		(progn 
			(setq temp pt1)
			(setq pt1 pt2)
			(setq pt2 temp)
		)
		)
		(setq ang (angle pt1 pt2))
)


(defun c:test ( / oldang oldsnap pt1 pt2 pt3 pt4 pt5 pt6 pt7)
(setq oldang (getvar 'aunits))
(setvar 'aunits 3)
(setq oldsnap (getvar 'osmode))
(setvar 'osmode 0)
(AH:getend)
(setq pt4 pt1 pt5 pt2)
(AH:getend)
(setq pt3  (mapcar '+ pt1 pt4) )
(setq pt3 (mapcar '(lambda (x) (/ x 2.0)) pt3))
(command "dimangular" pt4 pt1 pt3)
(setq ang (cdr (assoc 42 (entget (entlast)))))
(command "erase" "L" "")
(setq intpt (inters pt4 pt5 pt1 pt2))
(setq dist (getreal "\nEnter chord distance"))
(setq d2 (* (/ 1.0 (cos (- (/ pi 2.0) (/ ang 2.0)))) (/ dist 2.0)))
(setq pt6 (polar intpt (angle pt5 pt4) d2))
(setq pt7 (polar intpt (angle pt2 pt1) d2))
(command "line" pt6 pt7 "")
(setvar 'aunits oldang)
(setvar 'osmode oldsnap)
(princ)
)
(c:test)

 

  • Like 1
Link to comment
Share on other sites

  • 5 weeks later...

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