create arc

create arc

rpajounia
Advocate Advocate
1,684 Views
14 Replies
Message 1 of 15

create arc

rpajounia
Advocate
Advocate

so im trying to make an arc but my issue is the code im using is bulging out resulting into the red drawing im trying to make it look like the green drawing, can someone give me the code where i can give it a start and end point and it will draw the arc similar or close to the green where it looks nicer

 

my current code is 

0 Likes
Accepted solutions (1)
1,685 Views
14 Replies
Replies (14)
Message 2 of 15

Kent1Cooper
Consultant
Consultant

Maybe this is too obvious to point out, but the green are not "an arc."  But the two Arcs appear to be tangent to the white lines.  Is the idea that you want one Arc tangent to the white lines?  FILLET will do that when used with parallel Lines [the yellow here], ignoring whatever the Fillet radius setting is:

Kent1Cooper_0-1682531999111.png

If the bulging out of the red Arcs is because you need to meet a specific location with the midpoint, but you want one Arc tangent to the white Lines, do the Fillet and STRETCH the yellow and white to put the yellow's midpoint in the right place.  Or, if you can't change the white endpoint locations, but need tangency to them and the fixed midpoint location, do a half-ELLIPSE [cyan]:

Kent1Cooper_0-1682532314382.png

 

If I have misunderstood, explain in more detail.

Kent Cooper, AIA
0 Likes
Message 3 of 15

rpajounia
Advocate
Advocate

yes i do need it to meet a certain height, how would i be able to do this using code

0 Likes
Message 4 of 15

Kent1Cooper
Consultant
Consultant

@rpajounia wrote:

yes i do need it to meet a certain height....


In the yellow-Arc-with-white-Line-lengths-changed approach, or the cyan-Ellipse-with-white-Lines-unchanged approach?  How is the "certain height" specified?  As a distance above the level of the ends of the white Lines?  As a point [i.e. location, not a Point entity] through which the Arc or Ellipse should pass?  Something else?

Kent Cooper, AIA
0 Likes
Message 5 of 15

rpajounia
Advocate
Advocate

with the cyan, i would like to be able to give start point, end point, and top peak point

0 Likes
Message 6 of 15

Kent1Cooper
Consultant
Consultant

@rpajounia wrote:

with the cyan, i would like to be able to give start point, end point, and top peak point


ELLIPSE command, Arc option, pick those three locations [line endpoints in either order, followed by peak], and the right then left white-line endpoints to define the range of the elliptical arc.

Kent Cooper, AIA
0 Likes
Message 7 of 15

rpajounia
Advocate
Advocate

how do i do this with lisp code?

0 Likes
Message 8 of 15

Kent1Cooper
Consultant
Consultant

Describe the situation more.  What would exist already when the routine starts?  Are the Lines already there?  Would the User be asked to select them, or would they be unique in some way that a routine could find them without User selection?  Or would drawing them be part of the routine?  Or would the User be asked to pick on the endpoints of the Lines, not select the Lines as entities?  Would the ends of the Lines always be aligned, or might one of them need to be adjusted relative to the other?  Would the User be asked to pick a point for the height, or type in a number, or would the height or the Y coordinate of the peak already be known somehow?  Would it always be peak-up, or might the peak sometimes face in other directions?  Etc., etc.

Kent Cooper, AIA
0 Likes
Message 9 of 15

komondormrex
Mentor
Mentor

hey,

try the code below to draw arc you want to. select start point, end point and line tangent to arc.

 

 

 

(defun draw_arc (/ arc_1st_point arc_2nd_point tangent_line_object arc_center_point arc_aux_start_point half_included_angle
				   arc_start_angle arc_end_angle arc_radius 
				)
	(setq arc_1st_point (getpoint "\nPick 1st point of arc: ")
		  arc_2nd_point (getpoint arc_1st_point "\nPick 2nd point of arc: ")
		  tangent_line_object (vlax-ename->vla-object (car (entsel "\nPick tangent to arc line: ")))
		  arc_center_point (inters (setq arc_aux_start_point 
		  								(inters (trans (vlax-get tangent_line_object 'startpoint) 0 1)
												(trans (vlax-get tangent_line_object 'endpoint) 0 1)
												arc_1st_point
												arc_2nd_point
												nil
										)
								   )
								   (polar arc_aux_start_point (+ (* 0.5 pi) (vla-get-angle tangent_line_object)) 1) 
								   (setq mid_horde_point (polar arc_1st_point 
								   		  						(angle arc_1st_point arc_2nd_point) 
										  						(* 0.5 (distance arc_1st_point arc_2nd_point))
								   						 )
								   )
								   (polar mid_horde_point (+ (* 0.5 pi) (angle arc_1st_point arc_2nd_point)) 1)
								   nil
						   )
		  half_included_angle (atan (/ (distance arc_1st_point mid_horde_point) (distance arc_center_point mid_horde_point)))   
		  arc_start_angle (- (angle arc_center_point mid_horde_point) half_included_angle)
		  arc_end_angle (+ (angle arc_center_point mid_horde_point) half_included_angle)
		  arc_radius (distance arc_center_point arc_1st_point) 
	)
	(vla-addarc (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
				 (vlax-3d-point (trans arc_center_point 1 0))
				 arc_radius
				 arc_start_angle
				 arc_end_angle
	)
	(princ)
)
0 Likes
Message 10 of 15

Kent1Cooper
Consultant
Consultant

If the Line endpoints are aligned [same Y coordinate at the top end of vertical Lines], as in their sample drawing, I'm getting a divide-by-zero error from the (draw_arc) function.  It happens whether I pick the tangent Line at the 1st or 2nd point side, and whichever 1st-vs.-2nd order I pick them in, and with the Lines running in their original opposite directions or if I reverse one so they run in the same direction.

 

[But they don't actually want an Arc after all, anyway....]

Kent Cooper, AIA
0 Likes
Message 11 of 15

rpajounia
Advocate
Advocate

 so the lines are always going to be the same, user will will just need to give the 2 end points ( lines are already drawn ) and height of the arc 

0 Likes
Message 12 of 15

Kent1Cooper
Consultant
Consultant
Accepted solution

In simplest terms, without checking anything, something like this:

 

(defun C:CapLines (/ pt1 pt2 ht ptA)
  (setq
    pt1 (getpoint "\nEndpoint of Line 1: ")
    pt2 (getpoint "\nEndpoint of Line 2 aligned with 1: ")
    ht (getdist (mapcar '/ (mapcar '+ pt1 pt2) '(2 2 2)) "\nHeight of capping half-Ellipse: ")
  )
  (if (> (car pt2) (car pt1)) (setq ptA pt1 pt1 pt2 pt2 ptA)); switch so pt1 is right of pt2
  (command "_.ellipse" "_arc" "_non" pt1 "_non" pt2 ht pt1 pt2)
  (prin1)
)

 

It doesn't require the Lines to be vertical -- it will do this if at endpoints of parallel Lines aligned relative to the direction between them:

Kent1Cooper_0-1682611533071.png

but it will work as expected only in the more-upward-facing condition.  And it's up to you to use it in appropriate conditions -- it will do this kind of thing if there's an inappropriate relationship between Lines:

Kent1Cooper_1-1682611910540.png

and it will do it in isolation, unrelated to any Lines [or anything else].

 

You can give it the height by picking on-screen or by typing in a distance.

 

It could be made to [among other things]:
Ask for selection of the Line objects rather than locations, so it can test for alignment, and/or do it up-side-down, and put the Ellipse on the same Layer as [one of] the Lines [for a routine that does those things, and allows different object types as long as their ends align and face the same way, see CapEnd.lsp >here<];

Draw an Arc instead of an Ellipse if the height is equal to half the distance between the points;

Have the usual enhancements like *error* handling and Osnap control.

Kent Cooper, AIA
0 Likes
Message 13 of 15

rpajounia
Advocate
Advocate

amazing thank you!!!

0 Likes
Message 14 of 15

rpajounia
Advocate
Advocate

so can any1 help me modify this function, how it currently works is i give it the bottom left and top right of the lines and then how tall the arc should be, i was using circle but i want to change it into the arc how would i modify this?

 

Example

 

P1 = (list 0 0 0)

p2 = (list 250 250 0)

p3 = 100

 

end result should look like diagram ( just so you know how i would like it to look like )

 

(defun _arc ( p1 p2 p3 / lt point2d x1 y1 x2 y2 pts q)
      (defun lt (pt) (trans pt 1 0))
  
      (defun point2d (pt) (list (car pt) (cadr pt)))
        ;(command "_.ucs" "w")
      (setq
            x1 (apply 'min (mapcar 'car (list p1 p2)))
            y1 (apply 'min (mapcar 'cadr (list p1 p2)))
            x2 (apply 'max (mapcar 'car (list p1 p2)))
            y2 (apply 'max (mapcar 'cadr (list p1 p2)))
          pts (mapcar 'point2d(mapcar 'lt (list (list x1 y2 0) (list x1 y1 0) (list x2 y1 0) (list x2 y2 0))))
      )
      (cond
            ((and pts)
                  (setq q 
                       (entmakex (append (apply 'append
                              (cons
                                (list
                                    '(0 . "LWPOLYLINE")
                                    '(100 . "AcDbEntity")
                                    '(100 . "AcDbPolyline")
                                    '(410 . "Model")
                                    '(8 . "0")
                                    '(38 . 0)
                                    '(62 . 256)
                                    '(67 . 0)
                                    (cons 90 (length pts))
                                    '(70 . 1)
                                )
                                (mapcar 'list (mapcar '(lambda (a) (cons 10 a) ) pts))
                              )
                        )
			(list (cons 42 (/ p3 (/ (car p2) 2.0))))
		     )
                  )
			)
            )
      )

      q
)

 

 

0 Likes
Message 15 of 15

rpajounia
Advocate
Advocate

i got it to work with this code below but now lets say i want to break them back down into individual lines and individual arc. My reasoning for this is i combine it to nest it with other shapes and sizes and then i break it down for my cnc machine to cut it out

 

 

(defun _arc ( p1 p2 p3 / lt point2d x1 y1 x2 y2 pts q)
      (defun lt (pt) (trans pt 1 0))

      (defun point2d (pt) (list (car pt) (cadr pt)))
        ;(command "_.ucs" "w")
      (setq
            x1 (apply 'min (mapcar 'car (list p1 p2)))
            y1 (apply 'min (mapcar 'cadr (list p1 p2)))
            x2 (apply 'max (mapcar 'car (list p1 p2)))
            y2 (apply 'max (mapcar 'cadr (list p1 p2)))
          pts (mapcar 'point2d(mapcar 'lt (list (list x1 y2 0) (list x1 y1 0) (list x2 y1 0) (list x2 y2 0))))
      )
	(cond
	            ((and pts)
	                  (setq q (entmakex
	                        (apply 'append
	                              (cons
	                                (list
	                                    '(0 . "LWPOLYLINE")
	                                    '(100 . "AcDbEntity")
	                                    '(100 . "AcDbPolyline")
	                                    '(410 . "Model")
	                                    '(8 . "0")
	                                    '(38 . 0)
	                                    '(62 . 256)
	                                    '(67 . 0)
	                                    (cons 90 (length pts))
	                                    '(70 . 0)
	                                )
	                                (mapcar 'list (mapcar '(lambda (a) (cons 10 a)) pts))
	                              )
	                        )
	                  ))
	            )
	      )
  (setq
    pt1 (list 0 (cadr p2) 0)
  )
  (if (> (car p2) (car pt1)) (setq ptA pt1 pt1 p2 p2 ptA)); switch so pt1 is right of pt2
  (command "_.ellipse" "_arc" "_non" pt1 "_non" p2 p3 pt1 p2)
  (setq lastEnt (entlast))
(initcommandversion)
(command "_.join" q lastEnt "")
(setq q (entlast))
      q
)

 

 

0 Likes