JCLEE Posted December 25, 2023 Posted December 25, 2023 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. (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.") ) ) Quote
fuccaro Posted December 25, 2023 Posted December 25, 2023 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. Quote
JCLEE Posted December 25, 2023 Author Posted December 25, 2023 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? Quote
Recommended Posts
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.