Rotate with stretch program combination

Rotate with stretch program combination

Tolearnlisp
Enthusiast Enthusiast
6,112 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,113 Views
46 Replies
Replies (46)
Message 2 of 47

Sea-Haven
Mentor
Mentor

Yes, its obvious circuit board,  but a little complicated, Bricscad has an advantage here "Blockify" the little sq plines making a insert pt in middle. Find outer pline currently lines, find inner sq's then all crossing lines, do some form of matching end to sq, rotate and redraw with end to new sq location. There was a question recently about "Group" entities, this way would find all the little sq's before and after. 

 

Thinking a bit more a list using entity name  of each little sq and end/start & entity name  of each line, can not rely on user drawing from which end.

 

Some one may come up with stretch command method just not sure may have a play in the mean time.

 

The ultimate would be turn upside down.

Message 3 of 47

pbejse
Mentor
Mentor

@Sea-Haven wrote:
Thinking a bit more a list using entity name  of each little sq and end/start & entity name  of each line, can not rely on user drawing from which end.

Some one may come up with stretch command method just not sure may have a play in the mean time.

 


I was preparing to have fun with this, but problem is, layers at "0"?  the "plate" in the middle as LINE entities? Not sure if that is the status of the actual drawing. Nothing to use as filters to makes it loads easier to code.

 

I wont take part in this  until i see a better set of drawings to play with. 😊

 

0 Likes
Message 4 of 47

Tolearnlisp
Enthusiast
Enthusiast

@pbejse, Thanks.

I have uploaded the revised drawing. See attached sample V.2

I move the object to layer 1 and make the plate at the center as closed polyline.

Please check if this will now be ok and let me know if you have further concern. Thank you so much.

0 Likes
Message 5 of 47

pbejse
Mentor
Mentor

@Tolearnlisp wrote:

Please check if this will now be ok and let me know if you have further concern. Thank you so much.


 

Did i said I'll participate when the sample drawing is good enough to play with? Now i take that back 😁

It's good enough, at least now you are aware of the conditions to nake this thing works

 

- Make a selection of LWPOLYLINES with layer filter, preferably the plate is of a different layer as well

- retrieve entity name and points

- save to a list 

-- for the plate and the LWPOLYLINE on layer 1 [ list entity midpoint ]

-- for the thick lines (20) [ list entity pts ]

- rotate plate and layer 1 using plates mid

-- compare the list of centers to the end/start of the thick lines

-- change the pts of the thick line. ( 20 )

 

Start coding @Tolearnlisp 

 

 

 

Message 6 of 47

Moshe-A
Mentor
Mentor

Sorry guys to jump in but what about by start selecting these points by crossing and than picking a center point (the OP need to add a specific handle temp line) pressing enter twice (reaching  rotate) and start rotating?

 

Moshe

 

0 Likes
Message 7 of 47

hak_vz
Advisor
Advisor

This task is an example of affine transformations, we can say they are "partial" since transformation doesn't affect all entities. In particular case we have only rotation, but what if OP decide to add translation or even skew?

@Tolearnlisp  Can you assure that all connecting lines were created in direction towards center of the rectangle? 

 

I'll try to make my contribution to this subject later today.

 

 

 

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

ВeekeeCZ
Consultant
Consultant
Accepted solution

My version. For ACAD 2016+

 

(vl-load-com)

(defun c:RotateStretch ( / *error* m s p b w wl c cl dl d)
  
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
      (princ (strcat "\nError: " errmsg)))
    (setvar 'nomutt m)
    (princ))
  
  (setq m (getvar 'nomutt))
  
  (if (and (setvar 'nomutt 1)
	   (princ "\nSelect objects to stretch by window: ")
	   (setq s (ssget "_:S"))
	   (setvar 'nomutt m)
	   (or (vl-position (caar (ssnamex s)) '(2 3))
	       (prompt "\nError: Only crossing-window or crossing-polygon allows!"))
	   (setq p (mapcar 'cadr (cdr (last (ssnamex s)))))
	   (setq p (mapcar '(lambda (x) (trans x 0 1)) p))
	   (setq b (list (list (apply 'min (mapcar 'car p)) (apply 'min (mapcar 'cadr p)))
			 (list (apply 'max (mapcar 'car p)) (apply 'max (mapcar 'cadr p)))))
	   (setq w (ssget "_WP" p))
	   (setq wl (vl-remove-if 'listp (mapcar 'cadr (ssnamex w))))
	   (setq c (ssget "_CP" p))
	   (setq cl (vl-remove-if 'listp (mapcar 'cadr (ssnamex c))))
	   (setq dl (vl-remove-if '(lambda (x) (vl-position x wl)) cl))
	   (or (setq dl (vl-remove-if-not '(lambda (e) (and (= "LWPOLYLINE" (cdr (assoc 0 (entget e))))
							    (= 2 (cdr (assoc 90 (entget e)))))) dl))
	       (princ "\nNo wires of polylines of 2 vertices."))
	   (setq dl (mapcar '(lambda (e) (cons e (if (and (setq x (trans (vlax-curve-getstartpoint e) 0 1))
							  (< (caar b) (car x) (caadr b))
							  (< (cadar b) (cadr x) (cadadr b)))
						   (cons T (vlax-curve-getendpoint e))
						   (cons nil (vlax-curve-getstartpoint e)))))
			    dl))
	   )
    (progn
      (command-s "_.rotate" c "")
      (foreach e dl
	(setq d (entget (car e)))
	(entmod (subst (cons 10 (cddr e))
		       (assoc 10 (if (cadr e) (reverse d) d))
		       d)))))
  (*error* "end")
  )

 

Message 9 of 47

pbejse
Mentor
Mentor

@ВeekeeCZ wrote:

My version. For ACAD 2016+

 

(vl-load-com)

(defun c:RotateStretch ( / *error* m s p b w wl c cl dl d)
  ....
  (*error* "end")
  )

Well there you go. I stepped off a bit and  came back to see what the OP will come up with. 

@ВeekeeCZ  posted a  a quick solution. 😊

 

One thing i noticed is, its difficult to control the rotation, once or twice i twisted too far off and the wires go all wonky.

 

I'll write one of my own using the pseudo code i posted for the OP

 

 

Message 10 of 47

ВeekeeCZ
Consultant
Consultant

@pbejse wrote:

 

I'll write one of my own using the pseudo code i posted for the OP

 

👍  Interested to see...

0 Likes
Message 11 of 47

Kent1Cooper
Consultant
Consultant

Is this a job for simply using CONSTRAINTS on the inner ends of all those Lines?  I'm not versed in their use -- it might require placing a Point object in the middle of the little squares to constrain to.

Kent Cooper, AIA
0 Likes
Message 12 of 47

Kent1Cooper
Consultant
Consultant

@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 a Point in the center of some, and constrained the ends of the Polylines to those with GEOMCONSTRAINT [Coincident constraint, First point the CENter Osnap to the Circle or NODe Osnap to the Point, Second point the end of the Polyline].  ROTATE command, select all the middle Rectangle and the little squares and their Circles/Points, 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.

Kent Cooper, AIA
0 Likes
Message 13 of 47

pbejse
Mentor
Mentor

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


Ha! Party pooper!   But that's one heck of suggestion!

thumbsup.gif

 

 

0 Likes
Message 14 of 47

ВeekeeCZ
Consultant
Consultant

@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 a Point in the center of some, and constrained the ends of the Polylines to those with GEOMCONSTRAINT [Coincident constraint, First point the CENter Osnap to the Circle or NODe Osnap to the Point, Second point the end of the Polyline].  ROTATE command, select all the middle Rectangle and the little squares and their Circles/Points, 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.

0 Likes
Message 15 of 47

Kent1Cooper
Consultant
Consultant

@ВeekeeCZ wrote:
....

Disclaimer: I have no idea how to code constraints.


I didn't either, and some of the possibilities may be more challenging, but the Coincident one I figured out in a few minutes.  The trickiest part was to understand which is supposed to be the First point and which the Second -- the prompts don't make that very clear, but Help does.

Kent Cooper, AIA
0 Likes
Message 16 of 47

pbejse
Mentor
Mentor

@ВeekeeCZ wrote:

@pbejse wrote:

 

I'll write one of my own using the pseudo code i posted for the OP

 

👍  Interested to see...


Here you go, as described  at post # 5. I took the liberty of assigning layers, not leaving it as "1" "20" etc...

(defun c:stretchTheWires ( / stretchy _midof _points _midof e
			  ent pts lname gss match npt)
(defun _midof (ent /)
  (setq	p (_points ent))
  (mapcar (function (lambda (a b) (* (+ a b) 0.5))) (car p)(caddr p))
)
(Defun _points (ent)
  	(mapcar 'cdr (vl-remove-if-not '(lambda (d) (= (Car d) 10)) ent)))
  
(setq _sort (lambda (l)
	      (vl-sort l '(lambda (a b)(< (car a)(car b))))))  
		           
(if (setq stretchy nil solder nil gss (ssadd)
		ss (ssget "_:L" '((0 . "LWPOLYLINE")(8 . "PLATE,SOLDER,WIRES"))))	 
 (progn
   (repeat (setq i (sslength ss))
     (setq e   (ssname ss (setq i (1- i)))
	   ent (entget e) lname (strcase  (cdr (assoc 8 ent))))
     
     (cond
	     ((eq lname "WIRES") (setq stretchy (cons (list e (_points ent)) stretchy)))
	     ((eq lname "SOLDER")
	       (setq solder (cons (list	e (_midof ent )) solder
				  ) )(ssadd e gss) )
	       ((setq plate (list e (_midof ent )))(ssadd e gss)
		)
	    )
       )
	(command "_Rotate" gss "" "_non" (Cadr plate) pause )
	   (while (and (Setq a (car stretchy)) solder)
		   	(setq e (car a) pe (cadr a))
		   	(setq pair (mapcar  '(lambda (d)
			     (list (distance
				     (setq tp (vlax-curve-getclosestpointto e (Cadr d)))
					     (Cadr d))  tp d ) ) solder ))
			(setq pair (_sort pair) cmatch (cdr (car pair)))
			(setq ent (entget e) rep (_sort (mapcar '(lambda (m)
							   (list (distance (car cmatch) m) m)) pe)))
			(entmod  (subst (cons 10 (_midof (entget  (caadr cmatch))))
						(car  (member (cons 10 (cadr (car rep))) ent)) ent))
		   	(setq  stretchy (cdr stretchy)
			       solder (vl-remove (cadr cmatch) solder)
			       )
		            )
	   )
	  )
  (princ)
  )

Not pretty, also has that issue with rotating using mouse control. Wanting to include a loop to continue rotating, but i think that will be all the fun for today.

 

Maybe I will write another one using grread to mimic the constraint effect. 

 

Message 17 of 47

CADaSchtroumpf
Advisor
Advisor

Hello,

 

My idea:

With your sample drawing for see the steps.

First you use this lisp

(defun c:fix_pt_link ( / sel_cnct sel_brdg n dxf_ent l_pt_cnct frst_pt scnd_pt data js)
  (princ "\nSelect the CIRCLES set in red for fix the points.")
  (setq
    sel_cnct
    (ssget
      '(
        (0 . "CIRCLE")
        (100 . "AcDbEntity")
        (67 . 0)
        (410 . "Model")
        (8 . "1")
        (62 . 1)
        (100 . "AcDbCircle")
        (-4 . "<AND")
          (-4 . "<") (40 . 0.066)
          (-4 . ">") (40 . 0.065)
        (-4 . "AND>")
        (210 0.0 0.0 1.0)
      )
    )
  )
  (princ "\nSelect the POLYLINE set in layer \"20\" and make bridge with the fix points.")
  (setq
    sel_brdg
    (ssget
      '(
        (0 . "LWPOLYLINE")
        (100 . "AcDbEntity")
        (67 . 0)
        (410 . "Model")
        (8 . "20")
        (100 . "AcDbPolyline")
        (90 . 2)
        (70 . 0)
        (38 . 0.0)
        (39 . 0.0)
        (210 0.0 0.0 1.0)
      )
    )
  )
  (cond
    ((and sel_cnct sel_brdg (eq (sslength sel_cnct) (sslength sel_brdg)))
      (if (null (tblsearch "appid" "LINK_BRIDGE"))
        (regapp "LINK_BRIDGE")
      )
      (repeat (setq n (sslength sel_cnct))
        (setq
          dxf_ent (entget (ssname sel_cnct (setq n (1- n))))
          l_pt_cnct (cons (cons (cdr (assoc 5 dxf_ent)) (cdr (assoc 10 dxf_ent))) l_pt_cnct)
        )
      )
      (repeat (setq n (sslength sel_brdg))
        (setq
          dxf_ent (entget (ssname sel_brdg (setq n (1- n))))
          frst_pt (member (append (cdr (nth 5 (member '(90 . 2) dxf_ent))) '(0.0)) (mapcar 'cdr l_pt_cnct))
          scnd_pt (member (append (cdr (nth 10 (member '(90 . 2) dxf_ent))) '(0.0)) (mapcar 'cdr l_pt_cnct))
        )
        (if frst_pt
          (progn
            (setq
              frst_pt (car frst_pt)
              data (cons 5 (car (nth (vl-position frst_pt (mapcar 'cdr l_pt_cnct)) l_pt_cnct)))
            )
          )
        )
        (if scnd_pt
          (progn
            (setq
              scnd_pt (car scnd_pt)
              data (cons 10 (car (nth (vl-position scnd_pt (mapcar 'cdr l_pt_cnct)) l_pt_cnct)))
            )
          )
        )
        (if data
          (entmod
            (append
              dxf_ent
              (list
                (list -3
                  (list
                    "LINK_BRIDGE"
                    (cons 1002 "{")
                    (cons 1070 (car data))
                    (cons 1000 (cdr data))
                    (cons 1002 "}")
                  )
                )
              )
            )
          )
          (setq data nil)
        )
      )
      (setq js (ssget "_X" '((0 . "*") (8 . "1,20"))))
      (repeat (setq n (sslength sel_cnct))
        (setq ent (ssname sel_cnct (setq n (1- n))))
        (if (ssmemb ent js) (ssdel ent js))
      )
      (sssetfirst nil js)
    )
  )
  (prin1)
)

Use the command fix_pt_link and that must have selected the objects where that you can apply Move,Rotate or Scale with by exemple the grips

Then you have applied your changes, use this code by the command update_bridge. This retablihed the bridges between the jonctions points.

 

(defun c:update_bridge ( / js_brdg n dxf_ent xd_list vtx link pt)
  (setq js_brdg
    (ssget "_X"
      '(
        (0 . "LWPOLYLINE")
        (100 . "AcDbEntity")
        (67 . 0)
        (410 . "Model")
        (8 . "20")
        (100 . "AcDbPolyline")
        (90 . 2)
        (70 . 0)
        (38 . 0.0)
        (39 . 0.0)
        (210 0.0 0.0 1.0)
        (-3 ("LINK_BRIDGE"))
      )
    )
  )
  (cond
    (js_brdg
      (repeat (setq n (sslength js_brdg))
        (setq dxf_ent (entget (ssname js_brdg (setq n (1- n))) (list "LINK_BRIDGE")))
        (cond
          ((setq xd_list (assoc -3 dxf_ent))
            (setq
              vtx (cdr (assoc 1070 (cdadr xd_list)))
              link (cdr (assoc 1000 (cdadr xd_list)))
              pt (cdr (assoc 10 (entget (handent link))))
              pt (list (car pt) (cadr pt))
            )
            (entmod
              (append
                (reverse (cdr (member '(90 . 2) (reverse dxf_ent))))
                (subst (cons 10 pt) (nth vtx (member '(90 . 2) dxf_ent)) (member '(90 . 2) dxf_ent))
              )
            )
          )
        )
      )
    )
  )
  (prin1)
)

 

Message 18 of 47

pbejse
Mentor
Mentor

Another one that prompts the user to continue with the current selection. 

command: stretchTheWires

Select objects:

Choose[Enter to continue]<X ot exit>:

 

 
That will be it for me then.
 
Message 19 of 47

Kent1Cooper
Consultant
Consultant

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


BUT that wasn't quite the whole job -- some other things got off when Rotating the core stuff [Polylines not reaching their other-end locations].  In the attached further revised version, I added Coincident constraints to the other ends of the Polylines, and Fix constraints to the Circles those other ends are constrained to.  [And this time I did the inner constraints all with Point objects.]  Now [I think] it does exactly what you're after, with no routine required.

Kent Cooper, AIA
Message 20 of 47

ВeekeeCZ
Consultant
Consultant

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

BTW visually is much better temporarily HIDEOBJECTS of wirelines.

See HERE  

 

And yes, I think it would be possible to automate this. But as you said, a bit tricky.

0 Likes