Nikon Posted January 22 Author Posted January 22 (edited) 1 hour ago, GLAVCVS said: '(setq y (+ y (/ step 2.0)))' Thanks, the step Y is fine now. Separately, this code works correctly with WP, but together with the Circles_Chess_out code it works like CP. Even though I'm replacing CP with WP: (defun c:WP-count (/ pl lstent points conj ptx creaMTEXT altura) (defun creaMTEXT (texto altura / vlaEnt) (setq vlaEnt (vla-AddMText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-3d-point ptx) 50 (strcat "Count:\\P" (itoa (sslength conj))))) (vlax-put-property vlaEnt "Height" altura) ) (if (setq pl (car (entsel "\nSelect border polyline..."))) (if (= "LWPOLYLINE" (cdr (assoc 0 (setq lstent (entget pl))))) (setq points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) lstent ) ) ) ) ) (if points (progn (if (not altura1) (setq altura (getreal "\nHeight TEXT: ")) (setq altura (getreal (strcat "\nHeight TEXT (or ENTER for <" (rtos altura1 2 2) ">): "))) ) (if (not altura) (if altura1 (setq altura altura1) ) (setq altura1 altura) ) ) ) (if (and points altura (setq conj (ssget "_WP" points '((0 . "CIRCLE"))))) (if (setq ptx (getpoint (strcat "\nPick insertion point for objects number text <" (itoa (sslength conj)) "> (right click or ENTER for skip)..."))) (vla-AddText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (itoa (sslength conj)) (VLAX-3D-POINT ptx) altura) ) ) (princ) ) And I replace the height of the text in the line: (vla-AddText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (itoa circulos) (VLAX-3D-POINT ptx) (* radius 10.0)) (* radius 10.0) it seems a little strange to me, but it works and my text is 250 mm high. Sorry for asking so many questions, I just don't have much knowledge in lisp programming. Thank you for your patience and support! Edited January 22 by Nikon Quote
GLAVCVS Posted January 22 Posted January 22 (edited) I don't understand why you changed the selection mode. The mode should be '_cp', not '_wp' In the last code I attached it is as it should be. Don't touch it Edited January 22 by GLAVCVS 1 Quote
GLAVCVS Posted January 22 Posted January 22 As for '(*radius 10.0)', you should put a space between '*' and 'radius': '(* radius 10.0)' 1 Quote
Nikon Posted January 22 Author Posted January 22 (edited) 29 minutes ago, GLAVCVS said: As for '(*radius 10.0)', you should put a space between '*' and 'radius': '(* radius 10.0)' My code is correct I need a regime wp But the cp and wp in the code work the same way as the cp. The circles are selected inside the contour and on the contour, but I need only inside the contour... Edited January 22 by Nikon Quote
GLAVCVS Posted January 22 Posted January 22 Should I understand that you want to NOT draw circles whose centroid is on the perimeter line? Quote
Nikon Posted January 22 Author Posted January 22 (edited) 3 hours ago, GLAVCVS said: Should I understand that you want to NOT draw circles whose centroid is on the perimeter line? No, let them be drawn, but you don't need to take them into account when calculating the quantity. If you replace "CP" with "WP" in the code, the code still works as "CP". I just want to change the selection mode to "WP". Edited January 22 by Nikon Quote
Nikon Posted January 22 Author Posted January 22 (edited) On 21.01.2025 at 23:28, GLAVCVS said: That's it. Now it works. The code should work in AutoCAD 2015. I've tested it and it works. I've checked the updated code @LISP autocad 2015, but it doesn't work with complex polygons... Probably the problem is with my Autocad... Edited January 25 by Nikon Quote
GLAVCVS Posted January 22 Posted January 22 (edited) It's easy To not complicate the code further, simply add the code highlighted in blue in the image, in the same position as shown Edited January 22 by GLAVCVS 1 Quote
GLAVCVS Posted January 22 Posted January 22 As for what you say about AutoCAD 2015, it seems strange to me. Although I have heard somewhere that this version of AutoCAD does strange things. 1 Quote
GLAVCVS Posted January 22 Posted January 22 (defun c:Circles_Chess_outl (/ oddp ent step radius vlist minx miny maxx maxy x y row pt osmant circulos creaMTEXT ) ;;----------------------------------------------- ;; THE FUNCTION OF CHECKING WHETHER THE NUMBER IS ODD ;;----------------------------------------------- (defun oddp (n) (= (logand (fix n) 1) 1) ) ;;----------------------------------------------- ;; Local auxiliary functions ;;----------------------------------------------- ;; Extracting a list of vertices (points) of a linear 2D polyline: (defun getPolyVertices (e / ed lst pts) (setq ed (entget e) ;; selecting all groups of the DXF = 10 code (coordinates of the vertices) lst (vl-remove-if-not '(lambda (x) (= (car x) 10)) ed ) ;; turning them into a regular list of points (x y) pts (mapcar 'cdr lst) ) (if (vlax-get-property (vlax-ename->vla-object e) "Closed") (append pts (list (car pts))) pts ) ) ;; Checking whether the pt point is located inside the linear polygon v list: ;;; (defun pointInPolygon (pt vlist / cnt i v1 v2) ;;; (setq cnt 0 ;;; i 0 ;;; ) ;;; ;; "Let's "block" the list so that we can bypass the pair (list[i], list[i+1]): ;;; (setq vlist (append vlist (list (car vlist)))) ;;; (repeat (1- (length vlist)) ;;; (setq v1 (nth i vlist) ;;; v2 (nth (1+ i) vlist) ;;; i (1+ i) ;;; ) ;;; (if (edgeIntersectsRay pt v1 v2) ;;; (setq cnt (1+ cnt)) ;;; ) ;;; ) ;;; ;; If the number of intersections with the ray is odd, the point inside ;;; (if (= (logand cnt 1) 1) ;;; T ;;; nil ;;; ) ;;; ) (defun comprobar_centralidad (pto lst_ptos_rto / pt_inters+ pt_inters- n pt1 pt2 inters_negat inters_posit ) (setq n 0) (repeat (- (length lst_ptos_rto) 1) (setq pt_inters+ (inters pto (list (+ (car pto) 100000) (cadr pto)) (setq pt1 (nth n lst_ptos_rto)) (setq pt2 (nth (+ n 1) lst_ptos_rto)) ) ) (if (and pt_inters+ (not (member (cons 10 pt_inters+) lst_ptos_rto)) ) (if inters_posit (setq inters_posit (+ inters_posit 1)) (setq inters_posit 1) ) ) (setq pt_inters- (inters pto (list (- (car pto) 100000) (cadr pto)) pt1 pt2 ) ) (if (and pt_inters- (not (member (cons 10 pt_inters-) lst_ptos_rto)) ) (if inters_negat (setq inters_negat (+ inters_negat 1)) (setq inters_negat 1) ) ) (setq n (+ n 1)) ) ;;; (print (list (strcat "Punto: " (rtos (car pto) 2 2) "," (rtos (cadr pto) 2 2)) inters_negat inters_posit)) (if (and (= (rem (if (not inters_negat) 0 inters_negat ) 2 ) 0 ) (= (rem (if (not inters_posit) 0 inters_posit ) 2 ) 0 ) ) nil T ) ) (defun creaMTEXT (texto altura / vlaEnt) (setq vlaEnt (vla-AddMText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-3d-point ptx) 50 texto)) (vlax-put-property vlaEnt "Height" altura) ) (defun creaCIRCULO (pto radio / vlaEnt) (setq vlaEnt (vla-AddCircle (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-3d-point pto) radio)) ) ;; Checking the intersection of the horizontal ray to the right of pt with the segment (v1,v2): (defun edgeIntersectsRay (pt v1 v2 / px py x1 y1 x2 y2) (setq px (car pt) py (cadr pt) x1 (car v1) y1 (cadr v1) x2 (car v2) y2 (cadr v2) ) ;; Let's ensure that (x1,y1) is "lower" than (x2,y2): (if (> y1 y2) (progn (setq x1 (car v2) y1 (cadr v2) x2 (car v1) y2 (cadr v1) ) ) ) ;; Intersection condition: (and ;; 1) py is strictly above the lower vertex and not higher than the upper one (> py y1) (<= py y2) ;; 2) px < abscissas of the intersection point of the ray with the segment (defun edgeIntersectsRay (pt v1 v2 / px py x1 y1 x2 y2 intersectX) (setq px (car pt) py (cadr pt) x1 (car v1) y1 (cadr v1) x2 (car v2) y2 (cadr v2) ) ) ;; Let's ensure that (x1,y1) is "lower" than (x2,y2) (if (> y1 y2) (setq x1 (car v2) y1 (cadr v2) x2 (car v1) y2 (cadr v1) ) ) ) ;; Counting the intersection coordinate (setq intersectX (if (/= y2 y1) (+ x1 (* (- py y1) (/ (- x2 x1) (- y2 y1)))) x1 ;; if the segment is horizontal, it is usually skipped. ) ) ;; We are returning (and ...), or nil (and (> py y1) ;; a point above the lower vertex (<= py y2) ;; and no higher than the top (> intersectX px) ) ) ;;----------------------------------------------- ;; the main part ;;----------------------------------------------- (setq ent (car (entsel "\nChoose a closed linear polyline: "))) (if (null ent) (progn (prompt "\nThe polyline is not selected. Completion.") (princ) ) (progn ;; 1) Step Request (setq step (getreal "\nEnter the step between the centers (??): ") ) (if (or (null step) (<= step 0.0)) (setq step 50.0) ;; the "backup" option ) ;; 2) Fixed radius (setq radius 2.0) ;; 3) List of vertices (minimum 3, otherwise not a polygon) (setq vlist (getPolyVertices ent)) (if (< (length vlist) 3) (progn (prompt "\nThe polyline has <3 vertices, and the contour is incorrect." ) (princ) ) (progn ;; 4) Defining bounding box (setq minx (apply 'min (mapcar 'car vlist)) maxx (apply 'max (mapcar 'car vlist)) miny (apply 'min (mapcar 'cadr vlist)) maxy (apply 'max (mapcar 'cadr vlist)) ) (prompt (strcat "\nboundary (bounding box) polyline:\n" " X: " (rtos minx 2 2) " ... " (rtos maxx 2 2) "\n Y: " (rtos miny 2 2) " ... " (rtos maxy 2 2) ) ) ;; 5) Building a grid "in a staggered manner" (setq row 0 y miny circulos 0 ) (setq osmant (getvar "osmode")) (setvar "osmode" 0) (while (<= y maxy) ;; For an odd row row, we shift X by step/2 (if (oddp row) (setq x (+ minx (/ step 2.0))) (setq x minx) ) (while (<= x maxx) (setq pt (list x y)) ;; If the center is inside the polyline, draw a circle. (if (comprobar_centralidad pt vlist) ;(pointInPolygon pt vlist) (progn ;;; (command "_.CIRCLE" pt radius) (creaCIRCULO pt radius) (setq circulos (+ circulos 1)) ) ) (setq x (+ x step)) ) (setq y (+ y step)) (setq row (1+ row)) ) (vla-regen (vla-get-activedocument (vlax-get-acad-object)) 0) (if (setq conj (ssget "_wp" vlist '((0 . "CIRCLE")))) (progn (princ (strcat "\nTotal number of cicles drawn: " (itoa circulos))) (setq circulos (sslength conj)) ) ) (if (setq ptx (getpoint "\nPick insertion point for circle number text (right click or ENTER for skip)...")) (vla-AddText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (itoa circulos) (VLAX-3D-POINT ptx) radius) ) (setvar "osmode" osmant) ) ) ) ) (princ) ) (defun c:WP-count (/ pl lstent points conj ptx creaMTEXT altura) (defun creaMTEXT (texto altura / vlaEnt) (setq vlaEnt (vla-AddMText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-3d-point ptx) 50 (strcat "Count:\\P" (itoa (sslength conj))))) (vlax-put-property vlaEnt "Height" altura) ) (if (setq pl (car (entsel "\nSelect border polyline..."))) (if (= "LWPOLYLINE" (cdr (assoc 0 (setq lstent (entget pl))))) (setq points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) lstent ) ) ) ) ) (if points (progn (if (not altura1) (setq altura (getreal "\nHeight TEXT: ")) (setq altura (getreal (strcat "\nHeight TEXT (or ENTER for <" (rtos altura1 2 2) ">): "))) ) (if (not altura) (if altura1 (setq altura altura1) ) (setq altura1 altura) ) ) ) (if (and points altura (setq conj (ssget "_cp" points '((0 . "CIRCLE"))))) (if (setq ptx (getpoint (strcat "\nPick insertion point for objects number text <" (itoa (sslength conj)) "> (right click or ENTER for skip)..."))) (vla-AddText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (itoa (sslength conj)) (VLAX-3D-POINT ptx) altura) ) ) (princ) ) 1 Quote
Nikon Posted January 22 Author Posted January 22 @GLAVCVS gracias, now the number of circles is counted only inside the contour. 1 Quote
Tharwat Posted January 22 Posted January 22 Are you trying to use these codes to distribute firefighting sprinklers? Quote
Nikon Posted January 22 Author Posted January 22 7 minutes ago, Tharwat said: Are you trying to use these codes to distribute firefighting sprinklers? No, I take into account the transverse reinforcement in monolithic walls and fixators in monolithic slabs. Quote
BIGAL Posted January 23 Posted January 23 For waffle slabs did something similar, you select pline shape and pick a control point then make an array in this case of 2 staggered rows of circles, Remove all circles touching or outside the shape so all done. Will see if can find time to provide some code. 1 Quote
Nikon Posted January 23 Author Posted January 23 5 hours ago, BIGAL said: Will see if can find time to provide some code. I'm interested in your decision, I'll be waiting... Quote
GLAVCVS Posted January 23 Posted January 23 7 hours ago, BIGAL said: Para las losas de rejilla hice algo similar: seleccioné la forma de la polilínea y elegí un punto de control, luego hice una matriz, en este caso de 2 filas escalonadas de círculos. Eliminé todos los círculos que tocaban o estaban fuera de la forma y listo. Veré si puedo encontrar tiempo para proporcionar algún código. Yes It is a good idea to optimize the space to allow for as many circles as possible. If Nikon does not mind modifying its original concept, the tessellation could be built from the first possible circle. However, it is still possible that a better fit in one area produces a mismatch in another. 1 Quote
GLAVCVS Posted January 23 Posted January 23 I suppose that an algorithm could be designed to control and optimize the distribution of the circles, so that the misalignments are proportional throughout the perimeter. But this would be costly in terms of work and time. 1 Quote
GLAVCVS Posted January 23 Posted January 23 Unless someone already has code for this, of course. Quote
Nikon Posted January 23 Author Posted January 23 6 hours ago, GLAVCVS said: Unless someone already has code for this, of course. Your last code suits me perfectly and speeds up the work very much, the only drawback with the selection mode in the WP contour is that the selection is not quite correct... 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.