Jump to content

align block to curve with 2 "base points" / car along curve


Recommended Posts

This is close I need to tune it a bit to make it work correctly. Your block needs to be correct size ie say 2400 between wheels where they touch the pline. If its a different measurement need to know that in code. I rescaled your block using bedit. Its called Holden now an Aussie car. They are palced with a spacing in this case I chose 0.5m




new block.dwg

Edited by BIGAL
Link to comment
Share on other sites

caralign_v11_lrm.dwgHere's an approach that will work if the curve is a spline.


The program assumes that the two points of a block that will be required to lie on the spline are the block's base point and a point a known distance (L) on the x axis of the block. The program sets the base point on the spline and then determines then determines the location of the second point on the spline via numerical methods, i.e., it make a series of guesses.  The first guess is a distance L along the spline. 


To use a spline in the sample file caralign_v11.dwg I modified the block named "auto" such that the radius of the two arcs are the same (0.35).  The modified block is named "auto-2". 



The distance between the centers of the arcs was not modified. It is 2.4846.  I then created a spline that closely represented the polyline path.

The green curve in the image below is that spline.  An offset spline (red) is created 0.35 from the "path" spline.  The program ArraySpline is then used with a distance of 2.4846. The user may specify the distance between each block instance.  In the example below I used 3. The offset curve is used as the path to guarantee that the arcs will be tangent to the original spline. 



The program could be easily modified to place a block at a specified location on a spline.

(defun C:ArraySpline (/ L A blockname path pt smax smax dmax sL more p ang sp dpt )
;  Adds a series of blocks along a spline.  The block's origin is placed on the spline.
;  The angle of the block is determined by a second point of the block a distance L in the X
; direction of the block.  The block's have a user defined  spacing of A. 
; L. Minardi 8/9/2023 
  (command "ucs" "w")
  (setvar 'osmode 0)
(setq L (getreal
	  "\nEnter distance between the block's base point and a point on the block's x axis: "
      A		(getreal "\nEnter distance to next block: ")
      blockname	(getstring "\nEnter block name: ")
;(setq L 1.3 A 1 blockname "block1") ; used for debugging
    path (car (entsel "\nSelect Path."))
    pt	 (vlax-curve-getStartPoint path)
    smax (vlax-curve-getEndParam path)
    dmax (vlax-curve-getDistAtParam path smax)
    sL	 (vlax-curve-getParamAtDist path L)
    more T				; flag for loop  
  (while more				; loop for adding blocks until end of spline is reached
    (setq p   (SplinePtAtDist path pt L) ; location on spline for block's second point
	  ang (/ (* (angle pt p) 180.) pi)
    (command "-insert" blockname pt 1 1 ang)
    (setq dp  (vlax-curve-getDistAtPoint path p) ; distance to p
	  sp  (vlax-curve-getParamAtPoint path p) ; parameter at p
	  pt  (vlax-curve-getPointAtDist path (+ dp A)) ; next block location
	  p   (vlax-curve-getPointAtDist path (+ dp A L)) ; initial guess for second point on spline 
	  dpt (vlax-curve-getDistAtPoint path pt) ; distance along spline to pt
    (if	(< (- sMax sp) sL)		; test if another block will fit on spline
      (setq more nil)
  )					; end  while

(defun SplinePtAtDist (path pt  L  / disPt p s spt sDelta i sgn err)
; find the point on a spline that is a distance L from the point pt, 
; path - spline object name
; pt - known point on the spline that is closer to the beinning of the spline
;      than the desired point p that is a straingt line distance L away.  
; L - distance between the block's base point and a point on its x axis.

(setq disPt  (vlax-curve-getDistAtPoint path pt)
      p	     (vlax-curve-getPointAtDist path (+ disPt L))
      s	     (vlax-curve-getParamAtPoint path p)
      spt    (vlax-curve-getParamAtPoint path pt)
      sDelta (/ (- s spt) 3)
      i	     0
      sgn 1
(while (< i 20) ; sets maximum interations for solution
(if (> L (distance pt p)) 
  (progn ; true, L > distance
    (if	(> (* sgn -1) 0)
      (setq sgn	   (* sgn -1)  ; reverse search diection 
	    sDelta (/ sDelta 2); halve the interval search size
  (progn ; false L not > distance
    (if	(< (* sgn -1) 0)
      (setq sgn	   (* sgn -1)
	    sDelta (/ sDelta 2)
(setq s	(+ s (* sgn sDelta))
      p	(vlax-curve-getPointAtParam path s)
;;;(command "point" p)  ; used for debugging
(setq i (+ i 1))
(setq err (/ (abs (- (distance pt p) L)) L))
(if (< err 0.001) (setq i 100)) ; exit loop if error acceptable
) ; end while
  (setq p p)
) ; end defun   



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

First of all, I would like to thank Mr. BIGAL and Mr. Irm for their support.  

Thanks to Mr. Irm's I understood the idea of precisely inserting blocks on a curve

Regarding Mr. Irm's code, I have a few questions about whether it would be possible to make the same code with pollinia and so that auto-2 could be spaced every 5th unit, I have written down the requests in detail below

1) my goal is to set a single auto-2 block every 5 units  This code  insert  blocks  step  by  step (one by one)  

2) the second important reason is that I try to avoid saltini because it is not visually accurate, can you do the same with pollnia?


3 Despite all my attempts, I cannot modify the code to insert it every 5 blocks
4 When I use your block which has modified geometry 200 then autolisp works. But if I create only block 01, auto lisp does not work correctly, it arranges the blocks horizontally without loops only with each click of the mouse cursor.


5 when I transform pollnies using autolisp (by Advisor marko_ribar available at https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/poly-line-to-sp-line/td-p/6379603 ) then the insertion of blocks ends in the place where the spline curve has a lot of points (photo 6)



Edited by panczykwaldemar
I'm atached draw
Link to comment
Share on other sites

@panczykwaldemar  There are several factors that affect the computational and display precision. Computationally, the statement:

(while (< i 20) ; sets maximum interations for solution

as noted sets the upper limit for how many guesses will be made before the program quits.

The statement:

(if (< err 0.0001)

Determines how closely the required length to the second point must be met.

Both of these value could be adjusted to yield more accurate results.  I experimented with a few values, e.g., set iterations to 100 and err to 0.00001.  These changes had little affect on the displayed results.  

After further analysis I've concluded that it is an error in how splines are displayed in AutoCAD.   In the following image a point was added using osnap nearest to the spline.  Note that is not exactly on the line.  Also note that the center of the selected arc is slightly off the spline.



I have found that the display error for splines is more pronounced as they get longer.  For example, the images below shows your spline trimmed and a detail of the arc/spline contact.



Note that the arcs touch the spline.

I suggest using arrayspline on trimmed portions of the spline.


Link to comment
Share on other sites

We are talking about car ramps here, having dealt with this problem where we had vehicle access into house properties. You are relying on the concreter to build the ramp, so a spline is a complicated shape, you need to set points along the ramp the more the better to make the shape to what you want. So maybe a peg every 1m, from a design point of view using arcs in a pline is much easier. In simple terms there is a G1-G2 answer where a car will not bottom out, the other answer was for a standard car AUS stds, a 13m radius will work every time.


We had a problem in one property where a 1 driver car was ok, add 3 passengers, it scraped.


The shape here is a custom one. 

  • Agree 1
Link to comment
Share on other sites

Thank you very much for showing the way, I spent a lot of time changing from circles to arcs on this solution, but seeing how the community shares solutions, I will also add a little bit from myself
Thank you again @BIGAL end @Irm. 🙂

inspiration 01 


inspiration 02 :)  for  the short a concrete mixer truck drove onto a bridge where the load limit is 16 tons  



Wid_Circle_200.lsp Wid_201.dwg

Link to comment
Share on other sites

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.

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