# Draw lines and circles with some rules

## Recommended Posts

Hi guys!

I've wrote this lisp in order to draw these circles + lines in a fasted way.

As you can see it doesn't work very good with the vertical edge of 30cm, but it works if I put 60cm..

The program asks me the following:

1. number of lines

2. number of circles for each line

3. 2 points where to draw them

4. side of the line I've just draw with the 2 points

```(defun C:pu (/ linea)
(setq n1 (getint "\nQuante legature? ") ;how many lines
n2 (getint "\nQuante file? ")) ; how many circles for each line

(command "_Line" pause pause "")
(setq linea (entlast))
;(command "_divide" linea (* 2 n1))

(setq p1 (cdr (assoc 10 (entget linea)))
p2 (cdr (assoc 11 (entget linea)))
dist (/ (distance p1 p2) (* 2 n1)))
(entdel linea)
(setq ref (getpoint))

(setq passo 0.16
dist1 0.08
n 0
j 1
)

(IF (> (nth 0 p1) (nth 0 p2))
(setq swap p2
p2 p1
p1 swap)
)
(IF (> (nth 1 p1) (nth 1 p2))
(setq swap p2
p2 p1
p1 swap)
)

;Horizzontal
(COND ((= (fix (nth 1 p1)) (fix (nth 1 p2)))
(IF (< (nth 1 ref) (nth 1 p1))
(setq passo (* passo -1)
dist1 (* dist1 -1)
)
)

(while (< n  n1 )
(setq i 1)

(Entmake (list (cons 0 "CIRCLE")
(cons 8 "SCHÖCK_BOLE")
(cons 10 (list (+ (nth 0 p1) (* j dist)) (+ (nth 1 p1) dist1) (nth 2 p1)))
(cons 40 0.035)
(cons 62 3)
)
)

(while (< i n2)

(Entmake (list (cons 0 "CIRCLE")
(cons 8 "SCHÖCK_BOLE")
(cons 10 (list (+ (nth 0 p1) (* j dist)) (+ (nth 1 p1) dist1 (* i passo)) (nth 2 p1)))
(cons 40 0.035)
(cons 62 3)
)
)
(setq i (+ i 1))
)

(entmake (list (cons 0 "LINE")
(Cons 8 "SCHÖCK_BOLE")
(cons 10 (list (+ (nth 0 p1) (* j dist)) (+ (nth 1 p1) dist1) (nth 2 p1)))
(cons 11 (list (+ (nth 0 p1) (* j dist)) (+ (nth 1 p1) dist1 (* (- i 1) passo)) (nth 2 p1)))
(cons 62 3)
)
)
(setq j (+ j 2)
n (+ n 1))
)

)

;VERTICAL
((= (fix (nth 0 p1)) (fix (nth 0 p2)))
(IF (< (nth 0 ref) (nth 0 p1))
(setq passo (* passo -1)
dist1 (* dist1 -1)
)
)

(while (< n  n1 )
(setq i 1)

(Entmake (list (cons 0 "CIRCLE")
(cons 8 "SCHÖCK_BOLE")
(cons 10 (list  (+ (nth 0 p1) dist1) (+ (nth 1 p1) (* j dist)) (nth 2 p1)))
(cons 40 0.035)
(cons 62 3)
)
)

(while (< i n2)

(Entmake (list (cons 0 "CIRCLE")
(cons 8 "SCHÖCK_BOLE")
(cons 10 (list  (+ (nth 0 p1) dist1 (* i passo)) (+ (nth 1 p1) (* j dist)) (nth 2 p1)))
(cons 40 0.035)
(cons 62 3)
)
)
(setq i (+ i 1))
)

(entmake (list (cons 0 "LINE")
(Cons 8 "SCHÖCK_BOLE")
(cons 10 (list  (+ (nth 0 p1) dist1) (+ (nth 1 p1) (* j dist)) (nth 2 p1)))
(cons 11 (list  (+ (nth 0 p1) dist1 (* (- i 1) passo)) (+ (nth 1 p1) (* j dist)) (nth 2 p1)))
(cons 62 3)
)
)
(setq j (+ j 2)
n (+ n 1))
)

)
)
)```

How can I handle non vertical/horizontal lines?

How can I draw in the corner as well?

Thanks!

Dennis

Edited by MastroLube

##### Share on other sites

Use the polar function to calculate the position of points, and the angle function to calculate the angle between two given points.

##### Share on other sites

One suggestion in your code you repeat the entmake multiple times this could exist maybe twice line,circle as you can use a defun that you pass the variables to, this is a standard type of thing in programming to not write bits of code repeatedly.

```(defun ML:Makeline (lay pt1 pt2 /  )
(entmake (list (cons 0 "LINE")
(Cons 8 Lay)
(cons 10 pt1)
(cons 11 pt2)
(cons 62 3)
)
)
)

; put at start
(setq clay "SCHÖCK_BOLE")

; example
(setq p1 (list  (+ (nth 0 p1) dist1) (+ (nth 1 p1) (* j dist)) (nth 2 p1)))
(setq p2 (list (+ (nth 0 p1) (* j dist)) (+ (nth 1 p1) dist1 (* (- i 1) passo)) (nth 2 p1)))
(ML:Makeline clay p1 p2)
```

##### Share on other sites

Thank you guys for your help!

Yes I should learn to code a little bit better my code looks always like a mess..

I'll try to fix it!

See you soon!

Dennis

Dennis

##### Share on other sites
Posted (edited)

Hello guys!!

Today I had some time to continue this project!

I've totally rewrote the code:

```(defun c:test (/)

(setq n1 2
n2 3
diam 0.035
dist_y 0.10

)

(command "_Line" pause pause "")
(SETQ ref   (GETPOINT)
linea (ENTLAST)
p1    (CDR (ASSOC 10 (ENTGET linea)))
p2    (CDR (ASSOC 11 (ENTGET linea)))
dist_x  (/ (DISTANCE p1 p2) (* 2 n1))
ang   (angle p1 p2)
)
(entdel linea)
;inversione in funzione di ref
(setq inv 1
k 1
)

(repeat n1 ;direzione X
(setq j 1)
(ML:Makeline  "SCHÖCK_BOLE"
(polar (polar p1 ang (* k dist_x)) (+ ang (* inv (/ pi 2))) (* 1 dist_y))
(polar (polar p1 ang (* k dist_x)) (+ ang (* inv (/ pi 2))) (* (- (* n2 2) 1) dist_y))
)

(repeat n2 ;direzione Y
; J=1;3;5 etc

(setq pnt (polar (polar p1 ang (* k dist_x)) (+ ang (* inv (/ pi 2))) (* j dist_y) ))

(Entmake (list (cons 0 "CIRCLE")
(cons 8 "SCHÖCK_BOLE")
(cons 10 pnt)
(cons 40 diam)
(cons 62 3)
)
)
(setq j (+ j 2))
)
(setq k (+ k 2))
)

)

(defun ML:Makeline (lay pt1 pt2 /  )
(entmake (list (cons 0 "LINE")
(Cons 8 Lay)
(cons 10 pt1)
(cons 11 pt2)
(cons 62 3)
)
)
)```

I'm very proud of that

Can you give me an hint please?

There is a REF point at the beginning.. I want to use this point to say the direction of my circles+lines instead of going always counterclockwise for external and clockwise for internal.. How can I check it? the INV goes "-1" or "+1" to consider that.

Do you think I need to write a new function to draw in the 45° direction for the edges?

Thanks for your help

Dennis

EDIT: maybe something like that but I don't like it very much.. The original idea is to divide the 90 degree in half (one line+circle at 45°) and in 3 parts (2 lines+circles at 30°). Any suggestion?

```(defun legatura_diagonale (a / j k)
(setq j 1
k 1)
(repeat n2 ;direzione Y
; J=1;3;5 etc

(setq pnt (polar p1 (+ ang (* inv a)) (* j dist_y) ))

(Entmake (list (cons 0 "CIRCLE")
(cons 8 "SCHÖCK_BOLE")
(cons 10 pnt)
(cons 40 diam)
(cons 62 3)
)
)
(setq j (+ j 2))
)
(ML:Makeline  "SCHÖCK_BOLE"
(polar p1 (+ ang (* inv a)) (* 1 dist_y))
(polar p1 (+ ang (* inv a)) (* (- (* n2 2) 1) dist_y))
)
)```

Edited by MastroLube
Fix

##### Share on other sites

Hi,

I tried not to change the way of coding you did so hope it is clear enough to you to learn from.

```(defun c:test (/ gap clr diam len p1 p2 p3 ang rot dis pcs div lft a b)
(setq gap  2
crl  3
diam 0.035
len  0.40
)
(if (and (setq p1 (getpoint "\nSpecify start point :"))
(setq p2 (getpoint "\nNext point :" p1))
(setq p3 (getpoint "\nSpecify direction of Lines & Circles :"))
(setq ang (angle p1 p2))
)
(progn
(setq rot (+ ang (* pi (if (minusp (sin (- (angle p1 p2) (angle p1 p3)))) 0.5 1.5)))
dis (/ (distance p1 p2) (1+ gap))
pcs dis
)
(repeat gap (ml:makeline "SCHÖCK_BOLE" (setq a (polar p1 ang pcs)) (setq b (polar a rot len)))
(setq div (/ (distance a b) (1+ crl))
lft div
)
(repeat crl
(ml:makecircle (polar a rot lft) diam)
(setq lft (+ lft div))
)
(setq pcs (+ pcs dis)
)
)
)
)
(princ)
)
(defun ml:makecircle (pnt diam)
(entmake (list (cons 0 "CIRCLE")
(cons 8 "SCHÖCK_BOLE")
(cons 10 pnt)
(cons 40 diam)
(cons 62 3)
)
)
)

(defun ml:makeline (lay pt1 pt2)
(entmake (list (cons 0 "LINE")
(cons 8 lay)
(cons 10 pt1)
(cons 11 pt2)
(cons 62 3)
)
)
)
```

##### Share on other sites

Maybe next version if the rectang is a pline then you only need imply Inside or out or none. No need to pick points. Look at this it has the co-ords of the corner point so can do the pt1-pt2 etc

```; pline co-ords example
; By Alan H
(defun getcoords (ent)
(vlax-safearray->list
(vlax-variant-value
(vlax-get-property
obj
"Coordinates"
)
)
)
)

(defun co-ords2xy ()
; convert now to a list of xy as co-ords are x y x y x y if 3d x y z x y z
(setq len (length co-ords))
(if (= (vla-get-objectname obj) "AcDbLwpolyline")
(setq numb (/ len 2)) ; even and odd check required

(setq I 0)
(repeat numb
(setq xy (list (nth i co-ords)(nth (+ I 1) co-ords) ))
; odd (setq xy (list (nth i co-ords)(nth (+ I 1) co-ords)(nth (+ I 2) co-ords) ))
(setq co-ordsxy (cons xy co-ordsxy))
(setq I (+ I 2))
)
)

; program starts here
(setq obj (vlax-ename->vla-object (car (entsel "\nplease pick pline"))))
(setq co-ords (getcoords obj))
(co-ords2xy) ; list of 2d points making pline
; co-ordsxy holds the list of points ((X Y)(X Y)...
```

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account