Reduce polyline Vertex as shown

Reduce polyline Vertex as shown

Automohan
Advocate Advocate
2,800 Views
9 Replies
Message 1 of 10

Reduce polyline Vertex as shown

Automohan
Advocate
Advocate

Need lisp for as shown in the Image

Arc.jpg

"Save Energy"
Did you find this reply helpful? If so please use the Accept as Solution
0 Likes
2,801 Views
9 Replies
Replies (9)
Message 2 of 10

Satish_Rajdev
Advocate
Advocate

For a quick start :

(defun c:test (/ i o s)
  (if (setq s (ssget '((0 . "*polyline"))))
    (repeat (setq i (sslength s))
      (setq o (vlax-ename->vla-object (ssname s (setq i (1- i)))))
      (command-s "_.arc"
		 (vlax-curve-getpointatdist o 0.)
		 (vlax-curve-getpointatdist o (/ (vla-get-length o) 2.))
		 (vlax-curve-getpointatdist o (vla-get-length o))
      )
    )
  )
  (princ)
)

 

Best Regards,
Satish Rajdev


REY Technologies | Linked IN | YouTube Channel


 

0 Likes
Message 3 of 10

ВeekeeCZ
Consultant
Consultant

@Satish_Rajdevwrote:

For a quick start :

...
      (command-s "_.arc"
		 (vlax-curve-getpointatdist o 0.)
		 (vlax-curve-getpointatdist o (/ (vla-get-length o) 2.))
		 (vlax-curve-getpointatdist o (vla-get-length o))
...

 


Although the simplicity of the code you should make sure that the middle point is AT A VERTEX. I would also add "_non" for osnaps.

0 Likes
Message 4 of 10

Kent1Cooper
Consultant
Consultant

@ВeekeeCZ wrote:

Although the simplicity of the code you should make sure that the middle point is AT A VERTEX. I would also add "_non" for osnaps.


If there won't be other stuff drawn in the immediate area of the middle of the "arc," you could explicitly add "_end" Osnap for each point, which would take care of both those concerns.  It would be possible to calculate the vertex location closest to the center, especially if they're evenly spaced as in the example, but Osnap to ENDpoint at that half-the-length point will get you there.  And at the ends, it will override any other running Osnap mode(s) that might throw off the locations.

 

But if there might be other stuff in the vicinity of the middle, it's possible that ENDpoint Osnap could lock onto part of that, rather than the Polyline.

 

For a related routine, see PolygonToCircle.lsp, >here<.  It needs an all-around closed regular polygon, rather than the partial in the example, but could give you some ideas.

Kent Cooper, AIA
0 Likes
Message 5 of 10

marko_ribar
Advisor
Advisor

Actually it's slightly more complex than @Satish_Rajdev posted... If Polyline is placed in 3D you have to transform points from WCS obtained by vlax-curve-xxx functions to OCS of polyline...

 

Something like this :

 

 

(defun c:test ( / LM:3pcircle unit v^v i o s lst pt1 pt2 pt3 ocs )

  (vl-load-com)

  ;; 3-Point Circle  -  Lee Mac
  ;; Returns the center (UCS) and radius of the circle defined by three supplied points (UCS).

  (defun LM:3pcircle ( pt1 pt2 pt3 / cen md1 md2 vc1 vc2 )
    (if
      (setq md1 (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) pt1 pt2)
            md2 (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) pt2 pt3)
            vc1 (mapcar '- pt2 pt1)
            vc2 (mapcar '- pt3 pt2)
            cen (inters md1 (mapcar '+ md1 (list (- (cadr vc1)) (car vc1) 0))
                        md2 (mapcar '+ md2 (list (- (cadr vc2)) (car vc2) 0))
                        nil
                )
      )
      (list cen (distance cen pt1))
    )
  )

  (defun unit ( v / d )
    (if (not (equal (setq d (distance '(0.0 0.0 0.0) v)) 0.0 1e-8))
      (mapcar '(lambda ( x ) (/ x d)) v)
    )
  )

  (defun v^v ( u v )
    (list
      (- (* (cadr u) (caddr v)) (* (caddr u) (cadr v)))
      (- (* (caddr u) (car v)) (* (car u) (caddr v)))
      (- (* (car u) (cadr v)) (* (cadr u) (car v)))
    )
  )

  (if (setq s (ssget '((0 . "*polyline"))))
    (repeat (setq i (sslength s))
      (setq o (vlax-ename->vla-object (ssname s (setq i (1- i)))))
      (setq pt1 (vlax-curve-getstartpoint o)
            pt2 (vlax-curve-getpointatparam o 1.0)
            pt3 (vlax-curve-getendpoint o)
            ocs (unit (v^v (mapcar '- pt3 pt1) (mapcar '- pt2 pt1)))
      )
      (mapcar 'set '(pt1 pt2 pt3) (mapcar '(lambda ( x ) (trans x 0 ocs)) (list pt1 pt2 pt3)))
      (if (setq lst (LM:3pcircle pt1 pt2 pt3))
        (progn
          (if (minusp (sin (- (angle pt1 pt3) (angle pt1 pt2))))
            (mapcar 'set '(pt1 pt3) (list pt3 pt1))
          )
          (entmake
            (list
               '(000 . "ARC")
                (cons 010 (car lst))
                (cons 040 (cadr lst))
                (cons 050 (angle (car lst) pt1))
                (cons 051 (angle (car lst) pt3))
                (cons 210 ocs)
            )
          )
        )
      )
    )
  )
  (princ)
)
Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 6 of 10

john.uhden
Mentor
Mentor

I don't think it's as simple as that.  The image depicts what we might think is one arc drawn through a bundle of points.  But that perception falls under the category called assumption.  I think that to confirm the perception would require solving for the radius point (center) of consecutive triplets of points to find if they are equal (with a fuzz factor of course).

I can provide you a 3PCIRCLE function if you need it.  It takes 3 points and returns the radius point if there is a solution, meaning there is no solution for 3 points along a straight line.  I must have gotten the inspiration from somewhere else 'cause it doesn't look like I thought it up on my own; I just put it to music.  Did Google exist in February 2000?

John F. Uhden

Message 7 of 10

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

@ВeekeeCZ wrote:

.. you should make sure that the middle point is AT A VERTEX. ....


If there won't be other stuff drawn in the immediate area of the middle of the "arc," you could explicitly add "_end" Osnap ....


Incorporating that, and some other simplifications:

(defun c:test (/ s i e)
  (if (setq s (ssget '((0 . "*polyline"))))
    (repeat (setq i (sslength s))
      (setq e (ssname s (setq i (1- i))))
      (command "_.arc"
        "_end" (vlax-curve-getStartPoint e)
        "_end" (vlax-curve-getPointAtParam e (/ (vlax-curve-getEndParam e) 2))
        "_end" (vlax-curve-getEndPoint e)
      )
    )
  )
  (princ)
)

The other simplifications:

 

The (command) function, without the -s, will do fine.

 

The (vlax-curve-...) functions don't need conversion to a VLA object, but can also work with the entity name.

 

The Start Point and End Point can be found directly -- they don't need to be calculated as being at 0 and end-length distances along the Polyline.

 

Also, @Automohan, the Subject of the thread is really not what you're asking about.  Your image is not a Polyline with a lot of vertices and another Polyline with a reduced number of vertices, but rather a Polyline and an Arc  [I can tell because the grips are different].  It could be as in the Subject line, if that's what you really need:

(defun c:testP (/ s i e)
  (if (setq s (ssget '((0 . "*polyline"))))
    (repeat (setq i (sslength s))
      (setq e (ssname s (setq i (1- i))))
      (command "_.pline"
        "_end" (vlax-curve-getStartPoint e)
        "_arc" "_second"
        "_end" (vlax-curve-getPointAtParam e (/ (vlax-curve-getEndParam e) 2))
        "_end" (vlax-curve-getEndPoint e)
        ""
      )
    )
  )
  (princ)
)

In either case, the possibility of other stuff drawn in the vicinity of the middle having some ENDpoint closer than one of the vertices can be prevented from causing an incorrect result by changing this line:

 

"_end" (vlax-curve-getPointAtParam e (/ (vlax-curve-getEndParam e) 2))

 

to this:

 

"_end" (vlax-curve-getPointAtParam e (fix (/ (vlax-curve-getEndParam e) 2)))

 

[assuming the original Polyline always has at least 3 vertices].

Kent Cooper, AIA
0 Likes
Message 8 of 10

john.uhden
Mentor
Mentor

Please educate me.  In what way are the grips different?  This is something that may be important to all of us.

With my pool liner company, the draftsmen can just "see" an arc  from point to point to point and draw one by eye.  Apparently, Ii's close enough, while I prefer to be more exact with my programming and impose stricter rules within my programs.  I don't think there were any differences in 2002, but maybe any differences that have come about since then would be helpful to them.

John F. Uhden

0 Likes
Message 9 of 10

Kent1Cooper
Consultant
Consultant

@john.uhden wrote:

Please educate me.  In what way are the grips different?  This is something that may be important to all of us. ....


For a single-arc-segment Polyline, there is no center-point grip as for an Arc.  And in newer versions, for a Polyline the middle-of-segment grip is a different shape than the endpoint grips, whereas for an Arc the endpoint and midpoint grips are all the same shape.

Kent Cooper, AIA
0 Likes
Message 10 of 10

john.uhden
Mentor
Mentor

Thank you for that information, though my aged eyes did not see any difference in the image that was posted.

So , I guess the OP had already solved his issue, except for erasing the polyline.  Of course it leaves me wondering how (and why) the the polyline got created in the first place.

I can understand my pool liner draftspeople.  They produce points around a freeform pool by entering A and B distances measured in the field from a baseline (A-B).  Then they interpret the shape (consisting of arcs and lines) until it looks right.  But in their case, a 1/4 inch is close enough because vinyl stretches.  What I am missing is the origin of the OP's situation and the exactness needed for his solution.  It may be that straight segments from point to point may actually be good enough and that the derived arc is not really important.

John F. Uhden

0 Likes