Copy block along polyline and align it based on 2 select points

Copy block along polyline and align it based on 2 select points

cool.stuff
Collaborator Collaborator
1,407 Views
15 Replies
Message 1 of 16

Copy block along polyline and align it based on 2 select points

cool.stuff
Collaborator
Collaborator

Hello 🙂

 

I've been searching for a lisp that given a selected block and a polyline, it copies the selected block and aligns it along the polyline given 2 two selected points (which may be both different than its insertion point), given a space between the first selected point.

 

I don't know if the direction is important to it, but it may be from left to right (the block copy direction).

 

Can someone give me a hand please?

 

Many thanks in advance 🙂

0 Likes
Accepted solutions (1)
1,408 Views
15 Replies
Replies (15)
Message 2 of 16

pendean
Community Legend
Community Legend
Can you show us a mockup of the final intent? start with MEASURE or DIVIDE commands using the BLOCK option then manually edit from there (unless those two commands actually do what you seek).
0 Likes
Message 3 of 16

cool.stuff
Collaborator
Collaborator

Thank you for your answer 🙂

 

I've attached an example of what I need.

 

It is a block, whose insertion point is arbitrary. I have a polyline and given two selected points and a block, i can copy equally spaced that block based on those 2 points along the polyline, ensuring that both points are always touching the selected polyline. The points may or may not belong to the block (it it is possible 🙂 would be perfect 🙂 )

 

The main idea would be to ask the user to select the objects to be copied, then two points to be the guidelines, the polyline (path) and the spacing between copies of selected objects. In this case, I dont know if it is possible to specify the point to which the distance between copies will be made or just to assume the left point of those 2 selected points. It may be also assumed that the path would be from left to right.

 

In my example, I placed random positions to illustrate.

 

Many many thanks for your help 🙂

0 Likes
Message 4 of 16

Sea-Haven
Mentor
Mentor

I think I have what you want I did this for a path driven by a forklift with wide loads. It was to see what it may hit. PS done in 2018.

 

SeaHaven_0-1727840403538.png

 

Message 5 of 16

cool.stuff
Collaborator
Collaborator

I think that would work great 🙂

I tried to work with your lisp but I managed to only do it with your example.

Could you please explain how to work? 🙂

 

Many thanks

0 Likes
Message 6 of 16

cool.stuff
Collaborator
Collaborator

Could you please make it work on a 2D (plane) drawing please? It would be easier for me 🙂

 

Many many thanks again 🙂

0 Likes
Message 7 of 16

Sea-Haven
Mentor
Mentor

You just edit the block name, "FORK" for your name and change the (setq cRad 1.5) ; forklift wheel base as the distance between the insertion point and second point. Expects the orientation of the block to be say left to right. May need to move insertion point in block. it follows a pline path, let me know how it goes.

 

Ps use this 2D to check vehicle driveways, have a car block different wheelbase.

 

I had to set the scale to 1000 and it failed on the spline I dont plan on spending time to work out why it did not work properly, works with normal plines including arcs

SeaHaven_1-1727917032534.png

 

 

Message 8 of 16

cool.stuff
Collaborator
Collaborator

@Sea-Haventhank you for your answer 🙂

Thanks for your explanation. I'll try as you said and say something 🙂

 

Many thanks again 🙂

0 Likes
Message 9 of 16

cool.stuff
Collaborator
Collaborator

Hello 🙂

 

I tried to follow your indications but I cant make it work.

The block's frontend "flies" over the polyline...

Could you please check my modification in my dwg? 🙂

 

Many thanks :))

0 Likes
Message 10 of 16

Sea-Haven
Mentor
Mentor

I have seen the problem before the arcs are going in wrong direction. Trying to remember what I did to fix. Have a old dwg will test code again on that. Will get back to you soon.

 

 

Message 11 of 16

john.uhden
Mentor
Mentor

@Sea-Haven ,

Seems to me that the user needs to see the polyline direction and then is asked whether to reverse it.  This very old function shows arrow glyphs pointing out the polyline direction.

Note:

  •   plist is a global list of the polyline vertices, including |z because this was written before LWpolys.
  •   blist is a global list of the polyline bulges
  •   looks like color should have been localized
  •   Unless you need my assistance, reversing is up to you.
   ;;----------------------------------------------
   ;; Function to grdraw directional arrow vectors:
   ;; (new as of 10-12-97)
   ;; (01-06-01) added abnormal extrusion detection
   ;;
   (defun @arrows ( / # |p10 |p11 |chord |ang -|ang |bulge |sign |delta |radius |rp |midp
                      |d |a1 |p1 |p2 |p3 ph color size dph)
      (if (setq color (getenv "AutoSnapColor"))
         (setq color (atoi color))
         (setq color 2)
      )
      (setq # 0
            ph   (/ (getvar "viewsize")(cadr (getvar "screensize"))) ; pixel height
            size 16
            |plen (length |plist)
      )
      (repeat (1- |plen)
         (setq |p10 (nth # |plist)
               |p11 (nth (@next# #) |plist)
         )
         (if (= (length |p10) 2)
            (setq |p10 (append |p10 (list |z)))
         )
         (if (= (length |p11) 2)
            (setq |p11 (append |p11 (list |z)))
         )
         (setq |p10 (trans |p10 |e 1)
               |bulge (nth # |blist)
               |p11 (trans |p11 |e 1)
               |ang (angle |p10 |p11)
              -|ang (- |ang pi)
               |midp (mapcar '* '(0.5 0.5 0.5)(mapcar '+ |p10 |p11))
               |d (* ph size)
               # (1+ #)
         )
         (if (= |bulge 0.0)
            (setq |p1 (polar |midp |ang (* |d 0.5)))
            (setq |sign (if (minusp |bulge) -1.0 1.0)
                  |chord (distance |p10 |p11)
                  |delta (* 4.0 (atan (abs |bulge)))
                  |radius (abs (/ |chord 2.0 (sin (/ |delta 2))))
                  |rp (polar |p10 (+ |ang (* (- pi |delta) |sign 0.5)) |radius)
                  |midp (polar |rp (angle |rp |midp) |radius)
                  |a1 (* |sign (atan (/ |d |radius 2.0)))
                  |p1 (polar |rp (+ (angle |rp |midp) |a1) |radius)
            )
         )
         (setq |p2 (polar |p1 (+ -|ang 0.3) |d)
               |p3 (polar |p1 (- -|ang 0.3) |d)
               dph (/ ph (cos 0.3) 0.5)
         )
         (grvecs (list color |p1 |p2 |p1 |p3 |p2 |p3))
         (repeat (fix (/ size 2))
            (setq |d (- |d dph)
                  |p1 (polar |p1 -|ang ph)
                  |p2 (polar |p1 (+ -|ang 0.3) |d)
                  |p3 (polar |p1 (- -|ang 0.3) |d)
            )
            (grvecs (list color |p1 |p2 |p1 |p3 |p2 |p3))
         )
      )
   )
 ;; It's intended to work inside a looped (grread 1 14) with this:
   ;; where |e and |viewsize and |viewcenter are globals
   (defun @checkview ()
      (if (or (not (equal |viewctr (getvar "viewctr")))
              (/= |viewsize (getvar "viewsize")))
         (progn
            (redraw)
            (redraw |e 3)
            (setq |viewctr (getvar "viewctr")
                  |viewsize (getvar "viewsize")
            )
            (@arrows)
         )
      )
   )

 

John F. Uhden

0 Likes
Message 12 of 16

Sea-Haven
Mentor
Mentor
Accepted solution

I had another go this seems to work ok now.

 

(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 2.8754)
(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 startang crad)(polar stpt endang 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 stpt intpt))

(command "Insert" "Auto" 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)

 I dont remember changing code. 

SeaHaven_0-1728172537395.png

 

Message 13 of 16

cool.stuff
Collaborator
Collaborator
Many thanks for your help 🙂

It works 🙂


PS there is a minor error between the polyline and the block's contact points. Not a big "error"/gap, but still exists. There is any way to reduce it? Many thanks again 🙂
0 Likes
Message 14 of 16

Sea-Haven
Mentor
Mentor

Not sure why but this is the center of the 2 circles. Note the subtle difference in the Y value.

Select point to identify coordinates:
X=184.2562109 Y=26.410995 Z=0
:
: ID
Select point to identify coordinates:
X=187.1315679 Y=26.4107988 Z=0

 

The line is not horizontal. The circles are ellipses this may be where the problem is.

 

Message 15 of 16

cool.stuff
Collaborator
Collaborator
I'll do as you say and I'll get back to you 🙂
Many thanks again for your help 🙂
0 Likes
Message 16 of 16

cool.stuff
Collaborator
Collaborator
Sorry for my mistake.
I've changed to circle instead of ellipsis and the results have improved.
The difference now is very reduced.
The base point should be as I've defined in my example right?
In this case in the contact of the back circle with the polyline, right? Then, the other point can be any, as long as it is aligned with the polyline and with the spacing length correctly defined?

Many thanks
0 Likes