Rotate with stretch program combination

Rotate with stretch program combination

Tolearnlisp
Enthusiast Enthusiast
6,106 Views
46 Replies
Message 1 of 47

Rotate with stretch program combination

Tolearnlisp
Enthusiast
Enthusiast

Hello Everyone,

 

Is it possible to have stretch+rotate combination in one command?

  Capture.PNG

I want to rotate the object found at the center at any angle but I would want the inner endpoints of the polyline move along with the rotated object and the outer endpoint would stay in the same location. It is like stretch function but instead of just moving of what you have selected you have option to rotate it. Thank you

See attached cad file for your reference

 

0 Likes
6,107 Views
46 Replies
Replies (46)
Message 21 of 47

pbejse
Mentor
Mentor
Accepted solution

Grread version. 

It mimics the constraint thingy  [ supposedly ] 😁

I know, I know, I just had to try ....

 

HTH
 
Message 22 of 47

Kent1Cooper
Consultant
Consultant

@ВeekeeCZ wrote:

It seems to me that FIX is not necessary. But it could be just a quick assumption.

....


There may be other ways to accomplish it.  But without something like that, I found that [at least some of] the Polylines kept their length when the inner stuff was rotated, and dragged the outer Circles out of place.  That's why I added the Fix constraints to those outer Circles.

Kent Cooper, AIA
0 Likes
Message 23 of 47

hak_vz
Advisor
Advisor
Accepted solution

As I promised earlier today, here is my code that uses affine transformations. In other words, "CHIP" object can be rotated and translated. Scaling and skewing is left intact.

 

Copy base rectangle to new position and rotate it how you like, or just rotate if that's ok for you. Code asks to pick rectangle at its starting and end position and performs affine transformations.

Code is huge so  take it in attachment. It's a bit late at my location,  so further explanation tomorrow if needed.

 

Untitled.png

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.
Message 24 of 47

Sea-Haven
Mentor
Mentor

I was thinking more along the lines of select all internal get the small plines can do as 4 sides find the corresponding pline 2 points, use a simple defun of ssget cp. Make a sort of complicated list with entity names so even rotated know small pline is attached to a certain other pline, Just do a end / start swap test on the single pline in caser user draws in both directions in and out. Just need some time.

 

 

0 Likes
Message 25 of 47

hak_vz
Advisor
Advisor

@Sea-HavenIn my code I use ssget CP option where box coordinates are clipping points. Entities inside box are rotated and translated, and for all crossing objects (lwpolylines) position of point inside the box (startpoint or endpoint) is recalculated and changed.

 

To create affine transformation matrix one would have to pick similar points on two objects (like in picture panorama stitching), but I compromised with Idea that original rectangle is copied so it scale stays intact and points direction is retained. I thing this is the fastest option. For my own use I'll add scale transformation  and some other stuff.

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 26 of 47

Kent1Cooper
Consultant
Consultant

Here's the drawing with Constraints in operation, simply ROTATE-ing the central stuff about the midpoint:
RotateStretch.gif

Kent Cooper, AIA
Message 27 of 47

Sea-Haven
Mentor
Mentor

We know who the winner is now.

0 Likes
Message 28 of 47

Tolearnlisp
Enthusiast
Enthusiast

Thank you @ВeekeeCZ,

 

Great! It works for me so far. 

0 Likes
Message 29 of 47

Tolearnlisp
Enthusiast
Enthusiast

@Kent1Cooper Thank you for your effort.

But I would preferred the routine made by @pbejse & @ВeekeeCZ im not that well verse with constraint and I want to use the code in any drawing not only this one.

 

0 Likes
Message 30 of 47

Tolearnlisp
Enthusiast
Enthusiast

Thank you for the collaboration @pbejse and @ВeekeeCZ,

@pbejse , is it possible to add anything that shows me the realtime angle while rotating the plate? and also add an option to enter and desired angle of rotation similar to what @ВeekeeCZ did? And this program would work perfectly according to my needs. Thank you in advance.

 

0 Likes
Message 31 of 47

Tolearnlisp
Enthusiast
Enthusiast

Thank you @hak_vz,

This work fine for me. I will save this code and will use it depends on the needs and situation. Thank you

Message 32 of 47

Sea-Haven
Mentor
Mentor

I stopped when Kent provided,

I had select around the internal box

Find all the little sq's get entity name 

Find touching pline/line check is start/end save co-ords

 

Up to now

Yes rotate could be enter angle (getangle 

Then rejoin all pline/line to mid pt of little sq's, done by know entity so redo 4 corner pts now rotated, can find mid of sq.

 

Will have a go time permitting a different method.

 

To kent just need 1 example in lisp sq to line using constraints then what I have done already would be easy to add to code as it already finds the little sq's and the touching line. something along entsel, entsel, constraint say circle & line.

 

 

 

(prompt "\nPick Bottom left then top right") ; outer box on circuit
(SETQ SS (SSget))
(setq ss2 ss) ; need for later
(repeat (setq x (sslength ss))
(setq en (ssname ss (setq x (- x 1))))
(setq len (vla-get-length (vlax-ename->vla-object en)))
(if (> len 0.5)(setq ss (ssdel en ss)))
)

 

 

 

 

 

0 Likes
Message 33 of 47

Sea-Haven
Mentor
Mentor

I can see how to do it but may need a extra line in say defpoints layer.

 

constrain.gif

 

Not sure about how to do with lisp. I think still easier match entities.

0 Likes
Message 34 of 47

pbejse
Mentor
Mentor

@Tolearnlisp wrote:

Thank you for the collaboration @pbejse and @ВeekeeCZ,

@pbejse , is it possible to add anything that shows me the realtime angle while rotating the plate?


 

For now i will just show the realtime angle , you can pick a point or press enter to accept what is shown on the command prompt which i think is enough for now till i get my hands on a PC.

 

Insert this line on the code at post # 21

(while (eq 5 (car (setq gr (grread T 15 0))))
  	(redraw)
  		(_RotateThis gss axispoint ( - (setq ang2 (angle axispoint (cadr gr))) ang ))
  		(setq ang ang2)
	(setq ndata (_FollowThePlate stretchy solder))
	(setq stretchy (Car ndata) solder (cadr ndata))
  	(grdraw axispoint (cadr gr) 1)
  	(princ (strcat "\nCurrent angle: " (rtos (/ (* ang 180.0) pi) 2 0)))
  				)

We may have to do some math thingy to show the proper angle when the user drags the mouse on the other direction.

 

HTH

 

 

Message 35 of 47

ВeekeeCZ
Consultant
Consultant

@ВeekeeCZ wrote:

@Kent1Cooper wrote:

@Kent1Cooper wrote:

Is this a job for simply using CONSTRAINTS on the inner ends of all those Lines?  ....


Yes!  See the attached version of the drawing.  I put a tiny Circle in the center of some of the squares, ... and constrained the ends of the Polylines to those with GEOMCONSTRAINT ...  ROTATE command, select all the middle Rectangle and the little squares and their Circles..., use Mid-of-2 Osnap for the rotation base point in the middle of it all, and those ends of the Polylines "follow" the constraining locations.


 

Nice idea! Now, how nice would be to that into code... I can imagine that it could work the same way as my routine, but wire lines would be nicely fixed. Just make a window around the chip and the ROTATE command would handle the rest.

Disclaimer: I have no idea how to code constraints.


 

Just to prove the concept but it looks like it could be feasible this way. 

Special thanks to @pbejse for being patient with me on this one.

 

(vl-load-com)

(defun c:RS ( / *error* cod cmd ntm osm ss pts bnd wp-ss wp-lst cp-ss cp-lst wir-lst wir-ss wpt-lst cir-lst)

  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
      (princ (strcat "\nError: " errmsg)))
    (setvar 'nomutt 1)
    (setvar 'cmdecho 0)
    (if wp-ss (command-s "_.delconstraint" wp-ss ""))  ;; remove these two lines if you want to keep constraints
    (if cir-lst (mapcar 'entdel cir-lst))              ;; this one too.
(command-s "_.unisolateobjects") (if nmt (setvar 'nomutt nmt)) (if cmd (setvar 'cmdecho cmd)) (if osm (setvar 'osmode osm)) (if doc (vla-endundomark doc)) (princ)) (if (and (setq doc (vla-get-activedocument (vlax-get-acad-object)) nmt (getvar 'nomutt) osm (getvar 'osmode) cmd (getvar 'cmdecho)) (not (vla-endundomark doc)) (not (vla-startundomark doc)) (setvar 'cmdecho 0) (setvar 'nomutt 1) (setvar 'osmode 0) (princ "\nSelect objects to stretch by window: ") (setq ss (ssget "_:S")) (or (vl-position (caar (ssnamex ss)) '(2 3)) (prompt "\nError: Only window or crossing-window allowed!")) (setq pts (mapcar 'cadr (cdr (last (ssnamex ss))))) (setq pts (mapcar '(lambda (x) (trans x 0 1)) pts)) (setq bnd (list (list (apply 'min (mapcar 'car pts)) (apply 'min (mapcar 'cadr pts))) (list (apply 'max (mapcar 'car pts)) (apply 'max (mapcar 'cadr pts))))) (setq wp-ss (ssget "_WP" pts)) (setq wp-lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex wp-ss)))) (setq cp-ss (ssget "_CP" pts)) (setq cp-lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex cp-ss)))) (setq wir-lst (vl-remove-if '(lambda (x) (vl-position x wp-lst)) cp-lst)) (setq wir-ss (ssadd)) (mapcar '(lambda (e) (ssadd e wir-ss)) wir-lst) (or (setq wir-lst (vl-remove-if-not '(lambda (e) (and (= "LWPOLYLINE" (cdr (assoc 0 (entget e)))) (= 2 (cdr (assoc 90 (entget e)))))) wir-lst)) (princ "\nNo wires of polylines of 2 vertices.")) (setq wpt-lst (mapcar '(lambda (e) (if (and (setq x (trans (vlax-curve-getstartpoint e) 0 1)) (< (caar bnd) (car x) (caadr bnd)) (< (cadar bnd) (cadr x) (cadadr bnd))) (vlax-curve-getstartpoint e) (vlax-curve-getendpoint e))) wir-lst)) (setq cir-lst (mapcar '(lambda (x) (entmakex (list '(0 . "CIRCLE") (cons 10 x) '(40 . 0.0001)))) wpt-lst)) (mapcar '(lambda (c w) (command-s "_.GcCoincident" "_a" c w "") T) cir-lst wir-lst) (foreach c cir-lst (ssadd c wp-ss)) (vl-cmdf "_.hideobjects" wir-ss "") (vl-cmdf "_.constraintbar" wir-ss "" "_Hide") (setvar 'nomutt 0) (setvar 'cmdecho 1) (setvar 'osmode osm) ) (progn (command "_.rotate" wp-ss "") (while (> (getvar 'cmdactive) 0) (command pause)))) (*error* "end") )

 

@Tolearnlisp This adds constraints and tiny circles, runs the rotate command, then removes all the constraints and circles. There are notes in the code for the case that you want to try to work with them.

Message 36 of 47

pbejse
Mentor
Mentor

@pbejse wrote:

...

We may have to do some math thingy to show the proper angle when the user drags the mouse on the other direction.

 


 

That is very nice @ВeekeeCZ 👍

 

FWIW: Here you go @Tolearnlisp , included the option to type in rotation

command: Twister

Current angle <Rotation/Any key to end>:  12 <--- real time rotation 
Current angle <Rotation/Any key to end>: -9 [ Clockwise direction ]
Current angle <Rotation/Any key to end>: -11

Current angle <Rotation/Any key to end>: -16 R
Enter Angle: 45

Current angle <Rotation/Any key to end>: 45

 

Attached lisp file: Twister.lsp 

twistThis.png

 

Message 37 of 47

Tolearnlisp
Enthusiast
Enthusiast

Thank you @ВeekeeCZ,

It works when I rotated it using my mouse and click for the new angle but when I tried to enter angle of rotation on the command line the other endpoints of the polyline were lost from the original position. See image.

Appreciate also you could add the realtime angle. Thank you.test.PNG 

0 Likes
Message 38 of 47

Tolearnlisp
Enthusiast
Enthusiast

Thank you @pbejse,

 

It works and I really like the added features as requested by me.

I was thinking if you can eliminate or replace this line of code so that it will not require specific layer name anymore to work but rather utilize the existing layer name in any drawing but definitely you still see 3 different layer for the (plate, solder and wires). Thank you.

Capture1.PNG

0 Likes
Message 39 of 47

ВeekeeCZ
Consultant
Consultant
Accepted solution

@Tolearnlisp wrote:

Thank you @ВeekeeCZ,

It works when I rotated it using my mouse and click for the new angle but when I tried to enter angle of rotation on the command line the other endpoints of the polyline were lost from the original position. See image.... 


 

Well, a bit surprisingly the (command-s) approach works better than the classic (getvar 'cmdactive) one.

 

(vl-load-com)

(defun c:RS ( / *error* doc ntm osm cmd ss pts bnd wp-ss wp-lst cp-ss cp-lst wir-lst wir-ss wpt-lst cir-lst)
  
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
      (princ (strcat "\nError: " errmsg)))
    (setvar 'nomutt 1)
    (setvar 'cmdecho 0)
    (if wp-ss (command-s "_.delconstraint" wp-ss ""))  ;; remove these two lines if you want to keep constraints
    (if cir-lst (mapcar 'entdel cir-lst))              ;; this one too.
    (command-s "_.unisolateobjects")
    (if nmt (setvar 'nomutt nmt))
    (if cmd (setvar 'cmdecho cmd))
    (if osm (setvar 'osmode osm))
    (if doc (vla-endundomark doc))
    (princ))
  
  (and (setq doc (vla-get-activedocument (vlax-get-acad-object))
	     nmt (getvar 'nomutt) osm (getvar 'osmode) cmd (getvar 'cmdecho))
       (not (vla-endundomark doc))
       (not (vla-startundomark doc))
       (setvar 'cmdecho 0) (setvar 'nomutt 1) (setvar 'osmode 0)
       (princ "\nSelect objects to stretch by window: ")
       (setq ss (ssget "_:S"))
       (or (vl-position (caar (ssnamex ss)) '(2 3))
	   (prompt "\nError: Only window or crossing-window selection allowed!"))
       (setq pts (mapcar 'cadr (cdr (last (ssnamex ss)))))
       (setq pts (mapcar '(lambda (x) (trans x 0 1)) pts))
       (setq bnd (list (list (apply 'min (mapcar 'car pts)) (apply 'min (mapcar 'cadr pts)))
		       (list (apply 'max (mapcar 'car pts)) (apply 'max (mapcar 'cadr pts)))))
       (setq wp-ss (ssget "_WP" pts))
       (setq wp-lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex wp-ss))))
       (setq cp-ss (ssget "_CP" pts))
       (setq cp-lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex cp-ss))))
       (setq wir-lst (vl-remove-if '(lambda (x) (vl-position x wp-lst)) cp-lst))
       (setq wir-ss (ssadd))
       (mapcar '(lambda (e) (ssadd e wir-ss)) wir-lst)
       (or (setq wir-lst (vl-remove-if-not '(lambda (e) (and (= "LWPOLYLINE" (cdr (assoc 0 (entget e))))
							     (= 2 (cdr (assoc 90 (entget e)))))) wir-lst))
	   (princ "\nNo wires of polylines of 2 vertices."))
       (setq wpt-lst (mapcar '(lambda (e) (if (and (setq x (trans (vlax-curve-getstartpoint e) 0 1))
						   (< (caar bnd) (car x) (caadr bnd))
						   (< (cadar bnd) (cadr x) (cadadr bnd)))
					    (vlax-curve-getstartpoint e)
					    (vlax-curve-getendpoint e)))
			     wir-lst))
       (setq cir-lst (mapcar '(lambda (x) (entmakex (list '(0 . "CIRCLE") (cons 10 x) '(40 . 0.0001)))) wpt-lst))
       (mapcar '(lambda (c w) (command-s "_.gccoincident" "_a" c w "") T) cir-lst wir-lst)
       (foreach c cir-lst (ssadd c wp-ss))
       (vl-cmdf "_.hideobjects" wir-ss "")
       (vl-cmdf "_.constraintbar" wir-ss "" "_hide")
       (setvar 'nomutt 0) (setvar 'cmdecho 1) (setvar 'osmode osm)
       (not (command-s "_.rotate" wp-ss "")))
  (*error* "end")
  )

 


@Tolearnlisp wrote:

... Appreciate also you could add the realtime angle. Thank you. 


Since you're at the native ROTATE command at the moment, you can watch the angle at the status bar.

Z9E3zK5E_1-1613981269134.png

 

 

Message 40 of 47

pbejse
Mentor
Mentor

@Tolearnlisp wrote:

Thank you @pbejse,

I was thinking if you can eliminate or replace this line of code so that it will not require specific layer name anymore to work but rather utilize the existing layer name in any drawing but definitely you still see 3 different layer for the (plate, solder and wires). Thank you.

 


If there are 3 different layers for "plate", "solder" and "wires" all you need to do is replace the those on the code with the equivalent names from your standard layer convention.  That's how easy it is. You think you can handel that?Unless youre telling me  they are not always the same layer names.  Now that is just bad practice and a bit twisted [ that's a good name for a program ]

 

I am not saying it cannot be done without layers, its just way easier with filters.

But nevertheless, here it is.

command:Twisted < - not to be confused with its older brother "twister" 

 

Refere to attached Twisted.lsp