Author Topic: Challenging part of lisp  (Read 3615 times)

0 Members and 1 Guest are viewing this topic.

laison

  • Guest
Challenging part of lisp
« on: November 20, 2010, 10:05:43 PM »
I am resubmitting this in hope that I will get finally put this to bed. Most of the code is finished (finally). I have been on this for a very very long time.

The reason for this lisp is once a component (ENT1) is added to the model is so that if there is another component (ENT2) at a different elevation and further down from where the component (ENT1) that was added to the model this lisp file will MOVE "ENT1" on a parrallel axis until the it lined up perpendicular to "ENT2" afterwhich the angle between both will then be calculated. ENT1 will then rotate but stay at that location.

It is a 3D autolisp routine. Everything is complete except for the rotation part.






Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Challenging part of lisp
« Reply #1 on: November 20, 2010, 11:57:19 PM »
Interesting problem. I suppose the issue really is what do you know about the entities and what information can be readily retrieved.

Are these blocks, solids, surfaces or a combination? Each one presents its own challenge.

What points are known?

Will the entities always be aligned parallel?

Are the entities always parallel in the X or Y direction?

For a simple alignment when the objects are aligned parallel to X or Y ...
Code: [Select]
;aligned on the X plane
(setq pt1 (subst (car pt2) (car pt1) pt1))
;aligned on the Y plane
(setq pt1 (subst (cadr pt2) (cadr pt1) pt1))

When the objects are not aligned on any axis, the angle of the parallel plane will have to be calculated from the three known points
Code: [Select]
;calculate the rotation angle relative to pt1 and pt3
;and get the maximum distance between pt1 and pt2
;strip Z data from points so we get the world plane intersection
(setq pt1a (list (car pt1)(cadr pt1))
        pt2a (list (car pt2)(cadr pt2))
        pt3a (list (car pt3)(cadr pt3))
)
(setq ang (angle pt3a pt1a) ;the effective angle of ENT1 parallel to XY plane
        ang2 (angtof "90" 4) ;the offset to make perp line
        dist (distance pt2 pt1) ;maximum distance between ENT1 and ENT2 (in XYZ plane)
)
;find the intersecting point between a line perpendicular to segment pt3/pt1 and a line parallel to pt3/pt1 originating at pt2
(setq pt4 (inters
                  pt2a
                  (polar pt2a ang dist)
                  (polar pt1 (+ ang ang2) dist)
                  (polar pt1 (- ang ang2) dist)
              )
)
;the new location of pt1
(setq newpt1 (list (car pt4) (cadr pt4) (caddr pt1)))

Now lets find the new PT3 point
Code: [Select]
;use the set of points from the previous example
;returns a point on segment newpt1/pt2
(setq newpt3 (polar newpt1 (angle newpt1 pt2) (distance pt1 pt3)))

All that is left now is to move and rotate ENT1 to the new points, however, since I don't know the relationship of PT1 to ENT1, we will have to use the move command.
Code: [Select]
;function for angle calculation
(defun acos (x)
  (atan (/ (sqrt (- 1 (* x x))) x))
)
;move ENT1
(vl-cmdf "_.move" ENT1 "" pt1 newpt1)
;get hypotenuse and adjacent side
(setq hyp (distance newpt1 newpt3)
        adj (distance (list (car newpt1)(cadr newpt1)) (list (car newpt3)(cadr newpt3)))
)
;rotate ENT1
(vl-cmdf "_.rotate3d" ENT1 "" "2" pt1 newpt1 (acos (/ adj hyp)))

Of course, everything here is untested and may contain errors. My trig is also rusty, so I may have the acos function incorrect.

I no longer have ACAD installed so I wrote this on the fly without the benefit of loading and testing anything. I'll let you do that.

Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

laison

  • Guest
Re: Challenging part of lisp
« Reply #2 on: November 21, 2010, 02:32:15 AM »
First I want to thank you for a suck a quick reply.

About your questions:

The  entities would be used in 2 softwares. Generic Autocad and Cadworx, but mostly in Cadworx. The files are dwgs., they are intelligent but not so like Bentley AutoPlant. The types of entities would be either piping are structural, but mostly piping. In the generic autocad I have 3D package that is very impressive but not intelligent. These are also dwgs. These are also piping are structural entities. The file that included generated this. I beleive that these are solids.

The points would be from corner of an 90 degree elbow or the intersection.of the tee (pt1), to the either center are endpoint of the elbow are the endpoint of the tee (branch) (pt2). From there that entity would then rotate (similiar to rotate by reference) to center of other entity (pt3).

As far as them always being in X, Y plane the answer is no.

Yes ent1 would always move parrallel to ent2 (destination).


Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Challenging part of lisp
« Reply #3 on: November 21, 2010, 03:22:56 AM »
The solution you want can't be achieved automatically without selecting a point at the intersection of the main and branch of ENT2.

Solids have no direction, they are just BLOBS, with no inherent intelligence ... though the center of each outlet can be selected manually, trying to select one of the 10 circles in the Tee programmatically unassisted will not be possible because the identity on ENT2 appears to be unknown to ENT1..

You will need to select either the rotation angle or the UCS to rotate ENT1.

Additionally, determinind if the branch of ENT2 and ENT1 are actually aligned is not possible automatically.

One solution is to generate center-lines for the pipe axis lines and build the Tees to suit the geometry.


Are the Tees generates as solids as required or are they originally blocks ??
« Last Edit: November 21, 2010, 03:27:24 AM by Kerry »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Challenging part of lisp
« Reply #4 on: November 21, 2010, 12:42:51 PM »
Without knowing 3 points, it is impossible to do.

Given the solution I provided above, the user will be required to select ENT1 (the object which will be moved and rotated) and will will be required to select PT1, PT2, and PT3 as described in your original post.

However, once those points are selected, it should be possible to get the solution you desire, but there will have to be lots of error checking and conditional operators.

Now, there is a chance it can be done entirely programmtically, but a few criteria would have to be true. First, you would have to select ENT1 and ENT2, then, you would have to obtain a 3d centroid of the solids. After getting the centroids, you would need to programmatically determine the orientation of ENT1. It shouldn't be terribly difficult though considering you already know much about the object, finally, you would use the orientation to generate pt3 programmatically, it isn't necessary to be precise, it merely has to be on a straight line representing the center of the side outlet.

Once you have those points, you can proceed to move ENT1 and rotate it as needed.

I built an example function that will move ENT1 to the correct orientation, but it doesn't work in all cases ... for example, if the angle of ENT2 doesn't intersect with the parallel plane of ENT1, the outlets will never align and you must adjust the rotation angle of ENT2 to match. To see the function in action, merely move ENT1 in either direction in the XY plane.

This can all be done programmatically if you have a set of known points that generate an alignment plane ... geometry 101 ;-)

Code: [Select]
(defun C:ObjAlign ()
  (prompt "\nSelect target object: ")
  (setq ent1 (car (entsel)))
  (setq pt2 (getpoint "\nSelect center of base object: " )
pt1 (getpoint "\nSelect center of target object: ")
pt3 (getpoint "\nSelect alignment point on target object: ")
  )
  ;;calculate the rotation angle relative to pt1 and pt3
  ;;and get the maximum distance between pt1 and pt2
  ;;strip Z data from points so we get the world plane intersection
  (setq pt1a (list (car pt1) (cadr pt1))
pt2a (list (car pt2) (cadr pt2))
pt3a (list (car pt3) (cadr pt3))
  )
  (setq ang  (angle pt3a pt1a)
;;the effective angle of ENT1 parallel to XY plane
ang2 (angtof "90" 4)
;;the offset to make perp line
dist (distance pt2 pt1)
     ;;maximum distance between ENT1 and ENT2 (in XYZ plane)
  )
  ;;find the intersecting point between a line perpendicular to
  ;;segment pt3/pt1 and a line parallel to pt3/pt1 originating at pt2
  (setq pt4 (inters
      pt2a
      (polar pt2a ang dist)
      (polar pt1 (+ ang ang2) dist)
      (polar pt1 (- ang ang2) dist)
    )
  )
  ;;the new location of pt1
  (setq newpt1 (list (car pt4) (cadr pt4) (caddr pt1)))

  ;;use the set of points from the previous example
  ;;returns a point on segment newpt1/pt2
  (setq intpt (polar newpt1 (angle newpt1 pt2) (distance pt1 pt3)))
  (princ intpt)
  (setq newpt3 (inters (list (car intpt)(cadr intpt) -1000)
       (list (car intpt)(cadr intpt) 1000)
       newpt1
       pt2
       )
  )
  ;;current rotation angle
  (setq chyp (distance pt1 pt3)
cadj (distance (list (car pt1)(cadr pt1))
       (list (car pt3)(cadr pt3))
             )
  )
  (setq curang (rtd (acos (/ cadj chyp))))
  ;;target rotation angle
  (setq hyp (distance newpt1 newpt3)
adj (distance (list (car newpt1) (cadr newpt1))
      (list (car newpt3) (cadr newpt3))
    )
  )
  (setq tarang (rtd (acos (/ adj hyp))))
  (setq newang (- curang tarang))

  ;;move ENT1
  (vl-cmdf "_.move" ENT1 "" pt1 newpt1)

  ;;rotate ENT1
  (vl-cmdf "_.rotate3d"
   ENT1
   ""
   "2"
   pt1
   newpt1
   newang
  )
)

;;;function for angle calculation
(defun acos (x)
  (atan (/ (sqrt (- 1 (* x x))) x))
)
;;;Radians to Degrees
(defun rtd (a)
  (/ (* a 180.0) pi)
)
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Challenging part of lisp
« Reply #5 on: November 21, 2010, 03:27:14 PM »
laison 
 
I just noticed that the components have a block depicting the axis of the outlets.

I'm sure you will be able to use the block insert anr rotation to help ... after you select them.

 
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

laison

  • Guest
Re: Challenging part of lisp
« Reply #6 on: November 21, 2010, 09:05:24 PM »
Is there a way that once ent1 is moved to it's position where it's centers are perpendicular to each other that the UCS can be rotated so that the X and Y planes line up? Afterwhich the angle is calculated (in such as a getorient are a getangle) between the 2. Then the (command rotate by reference) would then rotate ent1 towards ent2.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Challenging part of lisp
« Reply #7 on: November 21, 2010, 09:44:37 PM »
About a dozen years+ ago I wrote a raceway modeling app that parametrically created solids to represent the various fittings. I needed to have control points, varying by fitting type so I could orient and align pieces relative to each other similar to the OP's requirements. I simply added xdata points (1011 group) to the objects; said data moving / scaling along with the objects. FWIW.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

myloveflyer

  • Newt
  • Posts: 152
Re: Challenging part of lisp
« Reply #8 on: November 21, 2010, 09:54:39 PM »
MP,Program can provide your! :evil:
Never give up !

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Challenging part of lisp
« Reply #9 on: November 21, 2010, 11:14:22 PM »
ummm, wut?

If you're asking for the program I cannot honor your request, it belongs to the company that paid for it.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Challenging part of lisp
« Reply #10 on: November 22, 2010, 10:48:08 AM »
CADWorx generally provides node objects at each connection point.  Additionally there is extensive XDATA associated with each component, making them quite intelligent but easier to use than AutoPLANT.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}