Path array: 2 seperate paths for measure and placement

Path array: 2 seperate paths for measure and placement

Anonymous
Not applicable
3,246 Views
16 Replies
Message 1 of 17

Path array: 2 seperate paths for measure and placement

Anonymous
Not applicable

Hi,

 

 

I need to array along path A at X distance and place objects on path B.   Same as the default arraypath command, but with separate paths for measure and placement.

 

 

I found this Path Array Displacement, but the measurement does not follow a path.

 

 

Has anyone come across a solution for this?

 

 

Cheers,

Shaun.

0 Likes
Accepted solutions (1)
3,247 Views
16 Replies
Replies (16)
Message 2 of 17

Kent1Cooper
Consultant
Consultant

Can you post an image or sample drawing?

Kent Cooper, AIA
0 Likes
Message 3 of 17

Anonymous
Not applicable

Hope this makes sense.

 

array.png

 

0 Likes
Message 4 of 17

Kent1Cooper
Consultant
Consultant

That looks achievable to me.  Are those red projection lines parallel to each other even if the "Array Measurement Path" is not straight [it's hard to tell from the image whether it is], or are they all projecting perpendicular from it?  [Or would it always be straight, in which case they would be both parallel to each other and perpendicular to it?]

Kent Cooper, AIA
0 Likes
Message 5 of 17

Anonymous
Not applicable

The measurement path is a curve.   Both paths are curves.  

 

The object is perpendicular to the measurement curve.

0 Likes
Message 6 of 17

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

The measurement path is a curve.   Both paths are curves.  

The object is perpendicular to the measurement curve.


Here's a quickie beginning, very lightly tested and without the usual controls, etc.  Currently, it draws a Circle  at a radius of one tenth of the array spacing at each projected location, just to prove the concept, but that can be replaced by a Block INSERTion, or a PASTECLIP, or whatever the nature of your object placement would be.  Depending on that, there could be different ways of orienting the objects -- in your image, they look like they're all oriented the same way, but they could be aligned with the object path, or probably some other possibilities.

 

[That command name is M, a numeral 1, capital-letter-O, and a 2.]

 

It doesn't account for an other-than-World Coordinate System, or protect against selecting inappropriate object types, or handle situations where the projections don't intersect the object path [e.g. if it's shorter than the measurement path], or if the object path doubles back and a projection intersects it more than once, or probably several other things that could be accounted for if needed, but see what you think so far in simpler situations.

 

(defun C:M1O2 ; = Measure along 1st path, place Objects along 2nd path
  (/ mpath opath opathobj spc dist mlin mlinobj)
  (setq
    mpath (car (entsel "\nPath for measurement: "))
    opath (car (entsel "\nPath for object placement: "))
    opathobj (vlax-ename->vla-object opath)
    spc (getdist "\nSpacing of locations along measurement path: ")
    dist 0
  ); setq
  (while (setq mpt (vlax-curve-getPointAtDist mpath dist))
    (command "_.line" "_none" mpt "_none"
      (polar
        mpt
        (+
          (angle ; calculate local direction
            '(0 0 0)
            (vlax-curve-getFirstDeriv mpath
              (vlax-curve-getParamAtPoint mpath mpt)
            ); getFirstDeriv
          ); angle
          (/ pi 2)
        ); +
        1
      ); polar
      ""
    ); command
    (setq
      mlin (entlast)
      mlinobj (vlax-ename->vla-object mlin)
    ); end setq
    (command
      "_.circle" "_none" (vlax-invoke mlinobj 'intersectwith opathobj acExtendThisEntity) (/ spc 10)
      "_.erase" mlin ""
    ); 
    (setq dist (+ dist spc))
  ); while
  (princ)
); defun
Kent Cooper, AIA
0 Likes
Message 7 of 17

john.uhden
Mentor
Mentor

@Kent1Cooper's method is very good.  I like his use of firstderiv to get the direction to the object's array location.  But I would like a clarification.  When you say "X distance", do you mean a distance in the WCS X direction, or is X just a symbol for a variable distance along the path, which distance (in either case) is specified by user input as a 'REAL?

 

Also, should the user be selecting an object to be arrayed?  And should the object always have an InsertionPoint property to be used for placement?  If yes to the selection, but no to the InsertionPoint, then the user would have to provide a base point relative to the selected object.  If no to the selection, then how will the object be specified, by a block name, an AutoCAD point, a circle, or what?  If a circle, then of what diameter?  If a block name, then we have to watch out for potential attributes if employing the "insert" command.  A better way would be to select an existing block reference and use vla-copy (which copies the object in place) and vla-move on the copy.  Then, except for a circle or a point, you must answer Kent's question about rotation angle as in either no change from the selected object, aligned with the object path, or aligned with the array path.

 

Also, should there be a change in layer or color or scale from the original?

 

Also also, should the constructed perpendicular lines remain or be deleted?

 

Also also also, what about dimensioning the array path?  If it is a curvy polyline then we can't use a regular aligned dimension without overriding the measurement default, which would be based on a straight distance vs. curved or partially curved.

 

Maybe I shouldn't be drinking tea in the afternoon.  😕

John F. Uhden

0 Likes
Message 8 of 17

Anonymous
Not applicable

Looks good.   It does what I need for the measurement path.   

 

If you could implement a base point for the start of measure and an alignment to path that would be perfect.

 

Really appreciate you taking the time to look at this.   Anything extra you can do would be great.   Thank you!!

0 Likes
Message 9 of 17

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

....If you could implement a base point for the start of measure and an alignment to path that would be perfect. ....


I assume you mean alignment to the object-placement path.  But the same question that's already been asked arises again: what is it that's to be placed?  A Block?  A User selection, possibly of more than one thing?  Text?  [Not some other things like Circles or Points, if alignment is desired.]

Kent Cooper, AIA
0 Likes
Message 10 of 17

Anonymous
Not applicable

I need to place a block and align in the same direction of the object path.   Its just a standard block that consists of lines and text.

0 Likes
Message 11 of 17

Kent1Cooper
Consultant
Consultant
Accepted solution

Give this a shot:

 

(defun C:M1O2 ; = Measure along 1st path, place Objects along 2nd path
  (/ mpath pt dist spc opath opathobj mlin mlinobj)
  (setq
    mpath (car (entsel "\nPath for measurement: "))
    pt (getpoint "\nLocation of first measurement point on it: ")
    dist (vlax-curve-getDistAtPoint mpath (osnap pt "_nearest"))
    spc (getdist "\nSpacing of locations along measurement path: ")
    opath (car (entsel "\nPath for object placement: "))
    opathobj (vlax-ename->vla-object opath)
  ); setq
  (while (setq mpt (vlax-curve-getPointAtDist mpath dist))
    (command "_.line" "_none" mpt "_none"
      (polar
        mpt
        (+
          (angle ; calculate local direction
            '(0 0 0)
            (vlax-curve-getFirstDeriv mpath
              (vlax-curve-getParamAtPoint mpath mpt)
            ); getFirstDeriv
          ); angle
          (/ pi 2)
        ); +
        1
      ); polar
      ""
    ); command
    (setq
      mlin (entlast)
      mlinobj (vlax-ename->vla-object mlin)
    ); end setq
    (command
      "_.insert" "YourBlockName"
        "_none" (setq pt (vlax-invoke mlinobj 'intersectwith opathobj acExtendThisEntity))
        "" "" ; X, Y
        (angtos
          (angle ; calculate local direction
            '(0 0 0)
            (vlax-curve-getFirstDeriv opathobj
              (vlax-curve-getParamAtPoint opathobj pt)
            ); getFirstDeriv
          ); angle
        ); angtos
      "_.erase" mlin ""
    ); command
    (setq dist (+ dist spc))
  ); while
  (princ)
); defun

It always progresses in the start-to-end direction along the measurement path [as AutoCAD stores that, which won't always be the way you thought you drew something, an Arc in particular], so you need to pick near its starting end -- it could be adjusted to either ask somehow for which way to progress, or to determine which end the first measurement point is closer to, and if appropriate, progress the other way.  But you may have situations in which you wouldn't want it to choose for you.

 

 

Same other limitations as before.

Kent Cooper, AIA
Message 12 of 17

Anonymous
Not applicable

I think it works!!   I have to test it out a bit further, but seems to do what I need so far.   

 

Thank you!!!

0 Likes
Message 13 of 17

Anonymous
Not applicable

It worked great the 1st time, but now I get errors.   Not sure where I went wrong.   

 

Error.png

0 Likes
Message 14 of 17

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

It worked great the 1st time, but now I get errors.   Not sure where I went wrong.

 


Did it work the 1st time on the same two paths at the same start location?  My first guess was that the projection misses the end of the object path, even by the tiniest bit, which would mean that this part:

 

(vlax-curve-getParamAtPoint opathobj pt)

 

would return nil instead of a number -- that's what the error message means, and it seems the only candidate [something that should be returning a number but isn't, within the rotation-angle calculation].  But I don't think that can be it, because then it shouldn't have found an insertion point.

 

Can you post the drawing [even just pared down to those two path objects, with the Block definition included]?

Kent Cooper, AIA
0 Likes
Message 15 of 17

Anonymous
Not applicable

I don't seem to be getting the same error.   Maybe user error.   I can get the lisp command working on most parts of my project.   One section still fails.

 

I have attached a sample file with the lines that I get errors.   

 

Error given:

 

Path for measurement:
Location of first measurement point on it:
Spacing of locations along measurement path: 15000

Path for object placement: Unknown command "M1O2". Press F1 for help.
Unknown command "M1O2". Press F1 for help.
; error: bad argument type: 2D/3D point: nil

 

 

 

Thanks again Kent.   You are a legend.   Saved me a lot of time.

 

0 Likes
Message 16 of 17

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

....Error given:

 

Path for measurement:
Location of first measurement point on it:
Spacing of locations along measurement path: 15000

Path for object placement: Unknown command "M1O2". Press F1 for help.
Unknown command "M1O2". Press F1 for help.
; error: bad argument type: 2D/3D point: nil

.... 


If you have command echoing off [CMDECHO System Variable], turn it on and run it again -- I'd be interested in what point in the process it reaches before getting that error.  Is it after it has put in some Blocks, or before it gets any of them in?  Is it at an end of the object path, as opposed to somewhere in the middle?  It's hard to evaluate from your drawing, without knowing whether it's the Ex2 or the MI2 Block you're placing, therefore which of the paths [grey or red] is the measurement path and which the object path, or which portion of them it failed on.

 

An unknown-command error with the command name you're in usually means an Enter [""] is coming at the command prompt, after some internal command, for which the Enter is supposed to be a valid input, has ended prematurely.  The Enter recalls [or tries to] the latest command entered at the command prompt, which is the one you're in, but that is not recognized within a (command) function, because that allows only native AutoCAD commands.

 

My guess:  If it's at an end [whether the beginning or the tail end], and the perpendicular projection from the measurement path doesn't quite hit the object path, then it won't find an insertion point, and if that kills the Insert command, it would mean both of those Enters intended for the scale factors would be causing the two unknown-command errors you got.  And the 2D/3D point: nil error would be consistent with its trying to do the next thing in the code [calculate the rotation angle] with no point having been found [even though it's sitting at the command prompt, not within an Insert command -- it will still run the calculation].

 

What happens if you LENGTHEN the end of the object path a little, at whichever end the problem occurs at?  If you do it by the Delta option with some nice round number, and that gets it to work, you could then un-Lengthen it back again with a negative Delta of the same round number, to restore it to its original length.

 

Or, if you join the multiple portions of object path into one Polyline, even if you keep the measurement path in several pieces, you won't run into such a not-quite-there end condition at the intermediate current ends of the pieces [because they won't be ends any more], but only possibly at the very ends.

 

Here's a question:  If the perpendicular projection from the measurement path misses the end of the object path, should a Block be placed at the end?  Or is there some requirement of what's being done that says only a true perpendicularly-projected location should get a Block placed at it?  The routine could check whether a point is found before trying to Insert, which would avoid the error but might miss Inserting a Block that you want Inserted.  If the two always nearly line up, and it's just a matter of slight divergence of angle that makes the projection miss, it could be made to put one at the end of the object path even when that's a hair short of meeting the perpendicular projection, if that doesn't violate something.

Kent Cooper, AIA
0 Likes
Message 17 of 17

Anonymous
Not applicable

You are correct about the perpendicular projection.    Projection from the measurement line missed the object line at the start.   I thought I checked that, user error again(I'll blame it on working too hard).   Some other errors were fixed by rebuilding the polylines and overkill them.   

 

 

grey=object path, red=measurement path, Ex2=object

 

 

CMDECHO was on already.

 

 

Seems to work perfectly.   Got the project finished.   Thanks again.

0 Likes