dividing a curve equaly

dividing a curve equaly

mitviz
Advocate Advocate
2,884 Views
15 Replies
Message 1 of 16

dividing a curve equaly

mitviz
Advocate
Advocate

I am trying to equally divide this curve but its not working out, how can i get this curve to divide equally in straight segments? as you can see from what i am doing when using the divide command this is what i getScreenshot 2021-04-29 033635.jpgScreenshot 2021-04-29 033723.jpg

0 Likes
2,885 Views
15 Replies
Replies (15)
Message 2 of 16

Kent1Cooper
Consultant
Consultant

As mentioned in your other topic, this is not going to be possible using DIVIDE, since it makes equal divisions along the length of the path object.  Chords between those points will vary in length where there's any variance in radius, change in direction, etc.  So it's going to need something like an AutoLisp routine, which means this is a better Forum.

 

The way to achieve what you want, if done manually, is to draw Circles for which the center of each new Circle is at the intersection of the previous Circle with the path object:

Kent1Cooper_0-1619693746941.png

The red segments will be of equal length if the Circles are of equal radius.

 

The problem comes in determining the radius of that Circle.  It can't be just a division of the length of the path, for the same reason that DIVIDE won't do what you want.  The correct-result radius will vary even among paths of the same length, if their shapes are different.

 

I suspect the only way to do it would be to start with a division of the path length for a radius, and have the routine actually draw Circles, and find where each intersects the path downstream to put the center of the next one, etc., until it gets all the way around.  Then it would need to look at how far off it was from meeting the overall length exactly, eliminate the previous round of Circles, make an estimate of how much to change the radius, and try again.  It could iterate this process, adjusting the radius by successively smaller amounts, until the result ends up within some tolerance of coming out right [within 0.1 units, or 0.01, or 0.001, or however precise you need it to be], but it would be only in the very rare instance that it can ever come out truly exactly.

 

Such a routine could be really interesting to watch work, planting Circles along the path, wiping them out, doing it again at an adjusted radius, wiping those out, etc.  I'm interested in trying to work something out, but it won't be right away.

Kent Cooper, AIA
Message 3 of 16

hak_vz
Advisor
Advisor

Why don't you try using command MEASURE that will create segments to length that is nearest to desires length.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 4 of 16

Kent1Cooper
Consultant
Consultant

@hak_vz wrote:

Why don't you try using command MEASURE that will create segments to length that is nearest to desires length.


[That has the same problem as DIVIDE, in that it measures along the length of the path, including curvature, and does not result in equal chord distances.]

Kent Cooper, AIA
0 Likes
Message 5 of 16

stevor
Collaborator
Collaborator

One way for only the curve section is to use the vlax-curve functions to get the distance,

divide by the target distance, get the closest integer of that fraction  to select a segment length. 

S
0 Likes
Message 6 of 16

Kent1Cooper
Consultant
Consultant

@stevor wrote:

.... get the distance, divide by the target distance ....


@mitviz, I assume, from your having started with the DIVIDE command, that what you will want as a target to divide the overall length by is a number of divisions, not a distance.  Is that correct?

Kent Cooper, AIA
0 Likes
Message 7 of 16

CADaSchtroumpf
Advisor
Advisor

Hi,

If for you is possible to fix the length of chord! You can try this

 

 

(defun l-coor2l-pt (lst flag / )
  (if lst
    (cons (list (car lst) (cadr lst) (if flag (caddr lst) 0.0))
      (l-coor2l-pt (if flag (cdddr lst) (cddr lst)) flag)
    )
  )
)
(defun draw_pt (pt col / rap)
  (setq rap (/ (getvar "viewsize") 50))
  (foreach n
    (mapcar
      '(lambda (x)
        (list
          ((eval (car x)) (car pt) rap)
          ((eval (cadr x)) (cadr pt) rap)
          (caddr pt)
        )
      )
      '((+ +) (+ -) (- +) (- -))
    )
    (grdraw pt n col)
  )
)
(defun c:measure_with_chord ( / js AcDoc Space ent vla_obj param_end pt_ref len_vtx nw_crcl lst_pt pt l_pt)
  (vl-load-com)
  (princ "\nSelect a curvilinear object on which you want to measure.")
  (while
    (not
      (setq js
        (ssget "_+.:E:S"
          (list
            (cons -4 "<OR")
              (cons -4 "<AND")
                (cons 0 "*POLYLINE,LINE,ARC,CIRCLE,ELLIPSE")
                (cons -4 "<NOT")
                  (cons -4 "&") (cons 70 112)
                (cons -4 "NOT>")
              (cons -4 "AND>")
              (cons 0 "SPLINE")
            (cons -4 "OR>")
          )
        )
      )
    )
  )
  (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (vla-StartUndoMark AcDoc)
  (setq
    Space
    (if (eq (getvar "CVPORT") 1)
      (vla-get-PaperSpace AcDoc)
      (vla-get-ModelSpace AcDoc)
    )
    ent (ssname js 0)
    vla_obj (vlax-ename->vla-object ent)
    param_end (vlax-curve-getEndParam vla_obj)
  )
  (redraw ent 3)
  (initget 1)
  (setq
    pt_ref (getpoint "\nMeasurement reference point: ")
    pt_ref (vlax-curve-getClosestPointTo vla_obj (trans pt_ref 1 0))
  )
  (draw_pt (trans pt_ref 0 1) 1)
  (initget 7)
  (setq len_vtx (getdist (trans pt_ref 0 1) "\nLength of chord: "))
  (while pt_ref
    (setq
      nw_crcl
      (vlax-invoke Space 'AddCircle
        pt_ref
        len_vtx
      )
    )
    (setq lst_pt
      (l-coor2l-pt
        (vlax-invoke
          nw_crcl
          'IntersectWith
          vla_obj
          acExtendThisEntity
        )
        T
      )
    )
    (cond
      (lst_pt
        (repeat (length lst_pt)
          (setq pt (vlax-curve-getClosestPointTo vla_obj (car lst_pt)))
          (if
            (and
              (> (vlax-curve-getParamAtPoint vla_obj pt) (vlax-curve-getParamAtPoint vla_obj pt_ref))
              (> param_end (vlax-curve-getParamAtPoint vla_obj pt))
            )
            (setq l_pt (cons pt l_pt) pt_ref pt)
          )
          (setq lst_pt (cdr lst_pt))
        )
      )
      (T (setq pt_ref nil))
    )
    (if (cadr l_pt)
      (if (equal pt (cadr l_pt) 1E-08)
        (setq pt_ref nil)
      )
    )
    (vla-delete nw_crcl)
  )
  (redraw)
  (redraw ent 4)
  (if l_pt (foreach i l_pt (vlax-invoke Space 'AddPoint i)))
  (vla-EndUndoMark AcDoc)
  (prin1)
)

Edit: Code corrected 20/06/2023

 

Message 8 of 16

mitviz
Advocate
Advocate

correct

0 Likes
Message 9 of 16

john.uhden
Mentor
Mentor

So long as there are no reverse curves, my PARKIT.lsp would provide the closest solution, except that it is meant to conquer the measure command, not divide.  It came about decades ago when another Irish maniac engineer told me that our plans would be rejected if we measured the widths of parking stalls by their arc length.  So I built one that computes where chord lengths would control.  But you see, I built it so that parking stalls would meet the requirement whether they were in a convex or concave segment, or part thereof.  I still consider it a damned good piece of work in spite of the fact that no review engineer would ever find a shortage anyway using the measure command unless he had our drawing file.  And certainly no one would ever find any shortages once painted... "Yep, that's about 9 feet."  God bless Bill Fitzgerald; he made me a better person.

John F. Uhden

0 Likes
Message 10 of 16

Sea-Haven
Mentor
Mentor

Like you, this is vehicle check and walks along a pline drawing a car to check for bottoming out, the must meet exact length is not required but code may be useful as a start method. Like you will have a think about the problem. If using circle may get 2 points using intersectwith.

 

(Defun draw_vehicle (  / crad startang endang dist len stpt num intpt ang)

(SETQ ANGBASEE (GETVAR "ANGBASE"))
(SETQ ANGDIRR (GETVAR "ANGDIR"))
(SETQ LUNITSS (GETVAR "LUNITS"))
(SETQ LUPRECC (GETVAR "LUPREC"))
(SETQ AUNITSS (GETVAR "AUNITS"))
(SETQ AUPRECC (GETVAR "AUPREC"))
(setq oldsnap (getvar "osmode"))

(SETVAR "LUNITS" 2)
(SETVAR "ANGBASE" 0.0)
(SETVAR "ANGDIR" 0)
(SETVAR "LUPREC" 0)
(SETVAR "AUNITS" 3)
(SETVAR "AUPREC" 0)
(setvar "osmode" 0)

(if (tblsearch "Block" "Holden")
(princ "Holden")
(progn
(command "-Insert" "holden.dwg" "0,0" 1 1 0)
(command "erase" "last" "")
) ; progn
)

(setq obj (vlax-ename->vla-object (car (entsel "\nPick Pline"))))

(setq interval ( getreal "\nEnter spacing m:"))

(setq cRad 3.05)
(setq startang (* pi 1.5))
(setq endang (/ pi 2.0))
(setq dist 0.0)

(setq len (vla-get-length obj))
(setq stpt (vlax-curve-getpointatdist obj interval))

(setq num (+ 1 (fix ( / len interval))))

(repeat num

(command "arc" "C" stpt (polar stpt endang crad)(polar stpt startang crad))
(setq objarc (vlax-ename->vla-object (entlast)))

(if (= (setq intpt (vlax-invoke obj 'intersectWith objarc acExtendnone)) nil)
(setq intpt (vlax-invoke obj 'intersectWith objarc acExtendThisEntity)) ; needed at start
)

(vla-delete objarc)
(setq ang (angle intpt stpt))

(command "Insert" "Holden" stpt 1 1 ang) ; need ang in radians

(setq stpt (vlax-curve-getpointatdist obj (setq dist (+ dist interval))))

) ; repeat

(SETVAR "LUNITS" lunitss)
(SETVAR "ANGBASE" angbasee)
(SETVAR "ANGDIR" angdirr)
(SETVAR "LUPREC" luprecc)
(SETVAR "AUNITS" aunitss)
(SETVAR "AUPREC" auprecc)

(princ)

) ; defun

(draw_vehicle)

 

0 Likes
Message 11 of 16

Sea-Haven
Mentor
Mentor

Progressing the factor is a step size i drew a 3 segment pline 500 each segment a rad of 100 did divide 16 the factor was like 1.06664 to get into 0.02 error. The more decimals the better. Need to do the stepping repeat did manually for testing so this is not finished. Happy for some one to add stepping algorithm need some more time.

 

 

; equal number of chords along a pline.
; By alanh May 2021 

(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
(if (and
	(= (getvar "tilemode") 0)
	(= (getvar "cvport") 1)
      )
    (setq acsp (vla-get-paperspace doc))
    (setq acsp (vla-get-modelspace doc))
)

(setq ent (entsel "\nPick the pline "))


(setq obj (vlax-ename->vla-object (car ent)))

(setq lenobj (vla-get-length obj))

(setq numch (getint "\nEnter how many segments "))

(setq chord (* (/ lenobj numch) factor)
	dist 0.0)
(setq start (vlax-curve-getstartpoint obj))
(setq end (vlax-curve-getendpoint obj))
(setq stpt start)
(setq lst '())
(setq lst (cons stpt lst))
(setvar 'osmode 0)
(repeat (- numch 1)
(vla-AddCircle acsp (vlax-3d-point stpt) chord )
(setq objarc (vlax-ename->vla-object (entlast)))
(setq intpt (vlax-invoke obj 'intersectWith objarc acExtendThisEntity))
(setq intpt1 (list (nth 0 intpt)(nth 1 intpt)(nth 2 intpt)))
(setq intpt2 (list (nth 3 intpt)(nth 4 intpt)(nth 5 intpt)))
(if (> (vlax-curve-getdistatpoint obj  intpt1)(vlax-curve-getdistatpoint obj  intpt2))
(setq intpt intpt1)
(setq intpt intpt2)
)
(setq lst (cons intpt lst))
(command "point" intpt)
(vla-delete objarc)
(setq stpt (vlax-curve-getpointatdist obj (setq dist (+ dist chord))))
)


(alert (strcat "error distance " (rtos (distance stpt end) 2 4)))

 

0 Likes
Message 12 of 16

nguyenphuthang1994
Participant
Participant
your program is very good, but why when there is a long polyline the program only runs out a few points and does not spread all the points on the line. can you fix it? I really need it
0 Likes
Message 13 of 16

nguyenphuthang1994
Participant
Participant

your program is very good, but why when there is a long polyline the program only runs out a few points and does not spread all the points on the line. can you fix it? I really need it, please! help me!

0 Likes
Message 14 of 16

CADaSchtroumpf
Advisor
Advisor

@nguyenphuthang1994  a écrit :
your program is very good, but why when there is a long polyline the program only runs out a few points and does not spread all the points on the line. can you fix it? I really need it

@nguyenphuthang1994 

You're right: a poorly done test prevented the code from running correctly.

I corrected the previously proposed code, I think it will work!

Thank for feedback.

 

Message 15 of 16

nguyenphuthang1994
Participant
Participant
yuh, so great! thank you, so much.
0 Likes
Message 16 of 16

nguyenphuthang1994
Participant
Participant

This is a program I have completed using AutoCAD .NET that addresses the issues mentioned above. You can download it and build a complete .dll application. With the source code I’m sharing, thank you everyone for your interest and support.

0 Likes