Jump to content

AutoLisp Help with Rotating Block to a desired point


Recommended Posts

Posted

Hello I need some help with Lisp code. I'm very new to coding so the logic is very simple minded.

So I'm using the code to arrange a block (block name is determined by the length of a polyline) between midpoint of two selected polyline.

I believe I accomplished this part, however I'm having a problem with orientation of a block.

I want to longest length of a block to be parallel to two selected polylines like image below.

I thought I could use a base point of a block (red circle center is a base point of a block) and rotate it as a reference point to make it parallel to either one of the polyline.

I'm not sure what kind of approach I need to take to accomplish this... Please suggest me a solution.   

Below is an image to show you what I want to lisp to perform  as an example after just selecting two polylines consecutively.

The image shows that two polylines are in angle of 45 degrees from x axis. 

 

spacer.png

(defun c:ArrangeTable2 nil
  (setq selectedPolyline1 (car (entsel "\nSelect the first polyline: ")))
  (setq selectedPolyline2 (car (entsel "\nSelect the second polyline: ")))
  (if (and selectedPolyline1 selectedPolyline2
           (member (cdr (assoc 0 (entget selectedPolyline1))) '("POLYLINE" "LWPOLYLINE"))
           (member (cdr (assoc 0 (entget selectedPolyline2))) '("POLYLINE" "LWPOLYLINE")))
      (progn
        (setq polylinePoints1 (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget selectedPolyline1))))
        (setq polylinePoints2 (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget selectedPolyline2))))

        ;; Ensure there are at least two points for each polyline
        (if (< (length polylinePoints1) 2)
            (princ "\nError: The first selected polyline must have at least two points.")
          (if (< (length polylinePoints2) 2)
              (princ "\nError: The second selected polyline must have at least two points.")
            (progn
              (setq startPoint1 (car polylinePoints1))
              (setq endPoint1 (cadr polylinePoints1))
              (setq startPoint2 (car polylinePoints2))
              (setq endPoint2 (cadr polylinePoints2))

              ;; Calculate the midpoints of the two polylines
              (setq midPoint1
                    (list (/ (+ (car startPoint1) (car endPoint1)) 2.0)
                          (/ (+ (cadr startPoint1) (cadr endPoint1)) 2.0)
                          0.0))

              (setq midPoint2
                    (list (/ (+ (car startPoint2) (car endPoint2)) 2.0)
                          (/ (+ (cadr startPoint2) (cadr endPoint2)) 2.0)
                          0.0))

              ;; Calculate the midpoint of the midpoints
              (setq finalMidPoint
                    (list (/ (+ (car midPoint1) (car midPoint2)) 2.0)
                          (/ (+ (cadr midPoint1) (cadr midPoint2)) 2.0)
                          0.0))

              ;; Calculate the angle between the finalMidPoint and the line connecting the end points of the two polylines
              (setq rotationAngle (angle finalMidPoint (polar finalMidPoint 1.0 (angle startPoint1 endPoint1))))

              ;; Calculate the average length of the two polylines
              (setq averageLength (/ (+ (distance startPoint1 endPoint1) (distance startPoint2 endPoint2)) 2.0))
              (setq blockName (strcat (rtos averageLength 2 0) "ec"))

              ;; Insert block at the calculated final midpoint with rotation
              (if (or
                    (tblobjname "BLOCK" blockName)
                    (findfile (strcat blockName ".dwg"))
                  )
                  (command "_.INSERT" blockName "_non" finalMidPoint 1.0 1.0 rotationAngle)
                  (alert (strcat "Block '" blockName "' missing"))
              )

              (princ (strcat "\nBlock '" blockName "' placed at final midpoint: " (rtos finalMidPoint 2 2)))
            )
          )
        )
      )
    (princ "\nError: Please select two valid parallel polylines.")
  )
)

 

Posted

Hello JCLEE, welcome in the forum!

You already have the start and end points calculated. There is an AutoLisp function that for two given points will return the angle of the line passing through those points. The function is called... angle. Just it will return the angle in radians, and your command prompt probably expects degrees. But it's easy to transform the results. So, to make the long story short: if you have two points, say p1 and p2, get the angle like this:
 

(setq ang1 (angle p1 p2))            ; get the angle
(setq ang1 (/ (* ang1 180.0) pi))    ; transform in degrees
(command "Insert"....... ang1)       ; use the result

I can't test it right now, I am on vacation until the 15th of January, but I think it will work...

In the future, if you will insert code in your posts, please use the CODE tag.

 

Posted

Thank you! this was a great help. It looks like it works as I intended to. Also I have one last question to ask. It keeps on displaying all the information of a block after selected block is placed. For example if a block name is 7200ec, it displays all th information such as x,y scale, angle, base point on a dialog box. I believe it's causing a lag and slowing the process of inserting next block. Is there a way to not display the result? should I get rid of princ function?

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...