Jump to content

A challenge: how to draw this? Floor heating ...


Recommended Posts

Posted (edited)

Hi to all CADTutors,

 

Every now and then I receive a drawing from a third party wich contains a floor heating plan. To be clear: I do not have to draw this myself, it is done by others.

 

But I can't keep myself from wondering how this is drawn. My guess is that there is some kind of reactor involved. Like in the Vlisp developers bible; in that case a garden path is drawn as example. The reactor makes sure the objects stay between the polyline.

 

So is this one, define a room (4 walls) and then define the floor heating. The program calculates various things and then projects the polyline as shown in the image.

 

1.jpg

 

The challenge / question is: how to automate this?

 

Maybe others in this forum know about floor heating or even have the answer...?

 

Smaal update: I now know (after some googling) that this is called under floor heating and that many people have requested this before. However I cannot find any solution.

Edited by Pietari
  • Like 1
Posted

To my observation at first glance d1 must be equal to d2, and radius r is half d1 (d2)... Also if D is smaller side of rectangle, then :

 

d=d1=d2

r=d/2

(rem D d)=0, or n=D/d, and n=(fix n), and n E (1,3,5,7,9,...,(2*k+1)); k E (0,1,2,3,...)

 

So real unknown variable is n

  • Like 1
Posted

You could probably start with the Dynamic Offset lisp routine developed by Lee Mac and modify it to obtain the desired results.

Posted

Hi Pietari, try this scratch

This create not good designed polyline in the middle,

you can edit them manually after

 
(defun C:fh(/ centx cnt d1 d2 dx dy lp n nxt osm p1 p2 p3 p4 pt1 pt2 pt3 pt4 pts pts2 rp wh)
(setq osm (getvar 'osmode))
(setvar 'osmode 1)
(setq lp (getpoint "\nLower left corner of room: ")
rp (getcorner lp "\nOpposite corner of room: ")
wh (mapcar '- rp lp)
dx (car wh)
dy (cadr wh)
d1 (getdist "Spacing of piping <300>: "))
(if (not d1)
(setq d1 300.0))
(setq d2 (getdist "Distance from wall <200>: "))
(if (not d2)
(setq d2 200.0))
(setq dx (- dx (* 2 d2))
dy (- dy (* 2 d2)))
(setq centx (/ dx 2))
(setq nxt (+ centx (* d1 2)))
(setq n 1)
(while (<= (setq nxt (+ nxt (* d1 2))) (+ dx (* 2 d2)))
(setq n (1+ n))
)
;recalculate gap between wall an pipeline
(setq d2 (/ (- dx (* (1- n) 2 (* d1 2))) 2))
(setvar 'osmode 0)
(setq cnt 1
pts nil
pts2 nil)
(setq pt1 (list (+ (car lp) (* cnt d2)) (cadr lp))
p1 (list (+ (car pt1) d1) (cadr lp))
pt2 (list (car pt1) (- (cadr rp) (* cnt d2)))
p2 (list (car p1) (- (cadr pt2) d1))
pt3 (list (- (car rp) (* cnt d2)) (cadr pt2))
p3 (list (- (car pt3) d1) (- (cadr pt3) d1))
pt4 (list (car pt3) (+ (cadr pt1) (* cnt d2)))
p4 (list (- (car pt4) d1) (+ (cadr pt4) d1)))

(setq pts (append pts (list pt1 pt2 pt3 pt4)))
(setq pts2 (append pts2 (list p1 p2 p3 p4)))
(while (< cnt n)
(setq pt1 (list (+ (car pt1) (* 2 d1)) (cadr pt4))
p1 (list (+ (car pt1) d1) (cadr p4))
pt2 (list (car pt1) (- (cadr pt2) (* 2 d1)))
p2 (list (car p1) (- (cadr pt2) d1))
pt3 (list (- (car pt3) (* 2 d1)) (cadr pt2))
p3 (list (- (car pt3) d1) (- (cadr pt3) d1))
pt4 (list (car pt3) (+ (cadr pt1) (* 2 d1)))
p4 (list (- (car pt4) d1) (+ (cadr pt4) d1)))
(setq pts (append pts (list pt1 pt2 pt3 pt4)))
(setq pts2 (append pts2 (list p1 p2 p3 p4)))
(setq cnt (1+ cnt))
)
(setq pts (append pts (reverse pts2)))
(command "pline")
(mapcar 'command pts)
(command "")
(setvar "filletrad" (/ d1 4.));; radius
(command "_fillet" "_P" "_L" )
(setvar 'osmode osm)
(princ)
)

Posted (edited)

Here is mine version... d1=d2 ... You only have to specify level of detail...

 

(defun makearc ( cen rad ang1 ang2 )
 (entmakex
   (list
     '(0 . "ARC")
     '(100 . "AcDbEntity")
     '(100 . "AcDbCircle")
     (cons 10 cen)
     (cons 40 rad)
     '(100 . "AcDbArc")
     '(210 0.0 0.0 1.0)
     (cons 50 ang1)
     (cons 51 ang2)
   )
 )
)

(defun makeline ( p1 p2 )
 (entmakex
   (list
     '(0 . "LINE")
     '(100 . "AcDbEntity")
     (cons 10 p1)
     (cons 11 p2)
     '(210 0.0 0.0 1.0)
   )
 )
)

(defun c:heat-spiral ( / CEN1 CEN2 CEN3 CEN4 D DD H INREC K N OSM P1 P2 P3 P4 P5 P6 P7 PST PTLST PTLSTN RAD REC SS Z )
 (setq osm (getvar 'osmode))
 (setvar 'osmode 0)
 (setq ss (ssadd))
 (setq rec (car (entsel "\nPick rectangle parallel to WCS axises with smaller side parallel to X axis")))
 (setq ptlst (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= (car x) 10)) (entget rec))))
 (setq d (distance (car ptlst) (cadr ptlst)))
 (initget 7)
 (setq k (getint "\nInput level of spiral turns (1,2,3,...) : "))
 (setq n (+ (* k 2) 1))
 (setq dd (/ d (float n)))
 (setq rad (/ dd 2.0))
 (vl-cmdf "_.offset" (* dd (float k)) rec (mapcar '(lambda ( a b c d ) (/ (+ a b c d) 4.0)) (car ptlst) (cadr ptlst) (caddr ptlst) (cadddr ptlst)) "")
 (setq ptlstn (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= (car x) 10)) (entget (setq inrec (entlast))))))
 (setq h (distance (cadr ptlstn) (caddr ptlstn)))
 (setq p1 (polar (cadr ptlstn) (* (/ pi 2.0) 3.0) rad))
 (setq pst (polar p1 (/ pi 2.0) dd))
 (makeline p1 pst)
 (ssadd (entlast) ss)
 (setq z -1.0)
 (repeat k
   (setq z (1+ z))
   (if (> z 1.0) (setq pst (mapcar '+ pst (list dd dd))))
   (if (/= z 0.0) (setq h (+ h (* 2.0 dd))))
   (if (/= z 0.0)
     (progn
       (makearc (setq cen1 (polar pst 0.0 rad)) rad pi (* (/ pi 2.0) 3.0))
       (ssadd (entlast) ss)
       (setq p2 (polar cen1 (* (/ pi 2.0) 3.0) rad))
       (setq p3 (polar p2 0.0 (* dd (* (- z 1.0) 2.0))))
       (if (/= z 1.0)
         (progn
           (makeline  p2 p3)
           (ssadd (entlast) ss)
         )
       )
       (makearc (setq cen2 (polar p3 (/ pi 2.0) rad)) rad (* (/ pi 2.0) 3.0) (* 2.0 pi))
       (ssadd (entlast) ss)
       (setq pst (polar cen2 0.0 rad))
     )
   )
   (makeline pst (setq p4 (polar pst (/ pi 2.0) (- h dd))))
   (ssadd (entlast) ss)
   (makearc (setq cen3 (polar p4 pi rad)) rad 0.0 (/ pi 2.0))
   (ssadd (entlast) ss)
   (setq p5 (polar cen3 (/ pi 2.0) rad))
   (setq p6 (polar p5 pi (* dd (* z 2.0))))
   (if (/= z 0.0)
     (progn
       (makeline p5 p6)
       (ssadd (entlast) ss)
     )
   )
   (makearc (setq cen4 (polar p6 (* (/ pi 2.0) 3.0) rad)) rad (/ pi 2.0) pi)
   (ssadd (entlast) ss)
   (makeline (setq p7 (polar cen4 pi rad)) (setq pst (polar p7 (* (/ pi 2.0) 3.0) (+ h dd))))
   (ssadd (entlast) ss)
   (if (= z 0.0) (setq pst p1))
 )
 (if inrec (entdel inrec))
 (vl-cmdf "_.pedit" "" "l" "y" "j" ss "" "")
 (setvar 'osmode osm)
 (princ)
)

(prompt "\nInvoke with : heat-spiral")
(princ)

M.R.

Edited by marko_ribar
changed Join function
Posted
You could probably start with the Dynamic Offset lisp routine developed by Lee Mac and modify it to obtain the desired results.

 

Hi ReMark, thanks for the reply. I believe the dynamic offset program by Lee is not what I am looking for. It only automates the process of offsetting dynamically.

 

Hi Pietari, try this scratch

This create not good designed polyline in the middle,

you can edit them manually after

 

Hi Fixo, thanks for the reply, this is indeed what I mean. There are some issues

like the middle spiral as you say. But the idea of selecting the room and then specifying the parameters is the way I think it should be.

 

Here is mine version... d1=d2 ... You only have to specify level of detail...

M.R.

 

Also thanks Marko; this result is the best. However to specify the amount is not quite the way it works I believe. More important is to specify the distance D1.

Another thing: D2 is not necessarily D1. I mean if D1 is 150 then it may be that D2 ends up being 100 or 200,... depends on what remains.

 

Thanks for the ideas, maybe even more to come, others?

Posted

Code slightly changed for lower side of rectangle... Also changed join option - it should work in any Acad version...

 

M.R.

Posted

Marko....you should be charging for this. Sweet!

Posted

This seemed like a fun challenge, so I thought I might participate...

 

Here is my version:

 

heatgrid.gif

 

The attached program will prompt for a rectangular closed LWPolyline and a 'wire spacing' (the distance between the coils), and will generate a maximal filleted spiral centered within the selected LWPolyline.

 

The program should perform successfully with all rectangular closed LWPolylines, at any rotation or orientation, and in all UCS & Views.

 

For an arbitrary rectangle of any dimension, one cannot specify both the spacing between the coils and the offset from the rectangle boundary, since multiples of these values will not necessary equate to the rectangular dimensions.

 

Hence, my program will prompt for the spacing between the coils and will center the spiral within the selected rectangular LWPolyline, maximising the number of spiral coils for the given spacing, with the division remainder equal to the offset from the boundary.

 

If the spacing is a multiple of the dimensions of the boundary, the program will offset the spiral from the boundary by the given spacing to ensure that the coils do not touch the boundary edge.

 

The code isn't pretty, but should hopefully perform correctly.

 

Interesting challenge!

HeatGridV1-0.lsp

  • Like 3
  • Thanks 1
Posted

Hello Lee,

 

Interesting challenge you say... I am amazed by the code / result. You must be good in mathematic. Thanks for the effort.

 

For an arbitrary rectangle of any dimension, one cannot specify both the

spacing between the coils and the offset from the rectangle boundary, since multiples of these values will not necessary equate to the rectangular dimensions.

 

Hence, my program will prompt for the spacing between the coils and will center the spiral within the selected rectangular LWPolyline, maximising the number of spiral coils for the given spacing, with the division remainder equal to the offset from the boundary. If the spacing is a multiple of the dimensions of the boundary, the program will offset the spiral from the boundary by the given spacing to ensure that the coils do not touch the boundary edge.

 

I understand, it works perfect just as is.

 

It would be cool to be able to say where the pipes should start / wich corner. Now it seems to use some starting point based on ?? because if I rotate the rectangle the program also changes the starting point once you run it again.

 

If I understand correctly then L shaped rooms will not be possible to process. Because of the calculations. Is here where the reactor may be used like in the Vlisp Developers bible 'garden path' lisp. Don't know really.

 

I googled a lot on 'underfloor heating lisp' and came across some code but none of them are as good as this one, I am sure it will be downloaded a lot in the future. Maybe you want to improve the program? Not only for me so any other input is welcome also.

 

[i](if *spacing* (strcat " <" (rtos *spacing*) ">: ") ": ")[/i]

Small question: Is it in general a good habit to put asterixes before / after global variable? Or just your way of doing it? I always put globals in the header like

;; spacing = global. Yours is easier to see in the code itself if its is global.

Posted
Interesting challenge you say... I am amazed by the code / result. You must be good in mathematic. Thanks for the effort.

 

Thank you Pietari, that's very kind of you.

 

It would be cool to be able to say where the pipes should start / wich corner. Now it seems to use some starting point based on ?? because if I rotate the rectangle the program also changes the starting point once you run it again.

 

Currently the program will construct the spiral emanating from the first vertex of the LWPolyline. The program could be modified to rotate the spiral by π radians, or mirror the result in the vertical/horizontal axis (relative to the rectangle); however, the program is constructed such that the central semi-circular curves are always aligned with the longest dimension of the rectangle.

 

Although these modifications could be incorporated, for the development time required it is far easier for the user to rotate/mirror the resultant LWPolyline as required using the standard AutoCAD commands.

 

If I understand correctly then L shaped rooms will not be possible to process. Because of the calculations.

 

Correct, the program is only designed for rectangular LWPolylines.

 

I googled a lot on 'underfloor heating lisp' and came across some code but none of them are as good as this one, I am sure it will be downloaded a lot in the future. Maybe you want to improve the program? Not only for me so any other input is welcome also.

 

Thank you Pietari, though, I doubt that I shall develop this program much further than the current draft - it was an enjoyable challenge to design & conceive the program, but I unfortunately could not justify devoting any more time to this project.

 

[i](if *spacing* (strcat " <" (rtos *spacing*) ">: ") ": ")[/i]

Small question: Is it in general a good habit to put asterixes before / after global variable? Or just your way of doing it? I always put globals in the header like

;; spacing = global. Yours is easier to see in the code itself if its is global.

 

As you may know, the only defining property of a global variable in comparison to a local variable is that the variable symbol is not declared in the list of local variables within the defun expression.

 

With this knowledge, I tend to use asterisks (or other more obscure characters) to reduce the probability that the symbol will be inadvertently redefined by another program; furthermore, as you have noted it also helps to distinguish the global variables in the code itself.

 

Cheers,

 

Lee

Posted

Thanks for the reply Lee.

I get your point of "time vs. develope", it's okay.

 

As you may know, the only defining property of a global variable in comparison to a local variable is that the variable symbol is not declared in the list of local variables within the defun expression.

Yes of course.

 

With this knowledge, I tend to use asterisks (or other more obscure characters) to reduce the probability that the symbol will be inadvertently redefined by another program; furthermore, as you have noted it also helps to distinguish the global variables in the code itself.

This: "will be inadvertently redefined by another program" is what I have not thought of. I will remember this one.

 

Thanks again to all who have put in some efforts.

Posted

You're very welcome Pietari, thank you for this interesting thread.

Posted (edited)

I changed my first code slightly, not to make 0 lengths lines, so in the end all entities will be joined correctly...

 

In addition, I decided to post this different version, based on my first algorithm... Who knows, maybe someone will use it too...

 

(defun makearc ( cen rad ang1 ang2 )
 (entmakex 
   (list
     '(0 . "ARC")
     '(100 . "AcDbEntity")
     '(100 . "AcDbCircle")
     (cons 10 cen)
     (cons 40 rad)
     '(100 . "AcDbArc")
     '(210 0.0 0.0 1.0)
     (cons 50 ang1)
     (cons 51 ang2)
   )
 )
)

(defun makeline ( p1 p2 )
 (entmakex
   (list 
     '(0 . "LINE")
     '(100 . "AcDbEntity")
     (cons 10 p1)
     (cons 11 p2)
     '(210 0.0 0.0 1.0)
   )
 )
)

(defun c:heat-spiral-2 ( / CEN1 CEN2 D DD H INREC K N OSM P11 P12 P21 P22 PST1 PST2 PTLST PTLSTN RAD REC SS Z )
 (setq osm (getvar 'osmode))
 (setvar 'osmode 0)
 (setq ss (ssadd))
 (setq rec (car (entsel "\nPick rectangle parallel to WCS axises with smaller side parallel to X axis")))
 (setq ptlst (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= (car x) 10)) (entget rec))))
 (setq d (distance (car ptlst) (cadr ptlst)))
 (initget 7)
 (setq k (getint "\nInput level of spiral turns (1,2,3,...) : "))
 (setq n (* k 2))
 (setq dd (/ d (float n)))
 (setq rad (/ dd 2.0))
 (if (/= k 1) 
   (progn
     (vl-cmdf "_.offset" (* dd (float (- k 1))) rec (mapcar '(lambda ( a b c d ) (/ (+ a b c d) 4.0)) (car ptlst) (cadr ptlst) (caddr ptlst) (cadddr ptlst)) "")
     (setq ptlstn (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= (car x) 10)) (entget (setq inrec (entlast))))))
   )
 )
 (if (not ptlstn) (setq ptlstn ptlst))
 (setq pst1 (polar (polar (car ptlstn) 0.0 dd) (/ pi 2.0) rad))
 (setq pst2 (polar pst1 (/ pi 2.0) (setq h (- (distance (cadr ptlstn) (caddr ptlstn)) dd))))
 (makeline pst1 pst2)
 (ssadd (entlast) ss)
 (setq cen1 (polar pst1 0.0 rad))
 (setq cen2 (polar pst2 pi rad))
 (setq z -1.0)
 (repeat k
   (setq z (1+ z))
   (makearc cen1 (+ (* z dd) rad) pi (* pi 2.0))
   (ssadd (entlast) ss)
   (makeline (setq p11 (polar cen1 0.0 (+ (* z dd) rad))) (setq p12 (polar p11 (/ pi 2.0) h)))
   (ssadd (entlast) ss)
   (makearc cen2 (+ (* z dd) rad) 0.0 pi)
   (ssadd (entlast) ss)
   (makeline (setq p21 (polar cen2 pi (+ (* z dd) rad))) (setq p22 (polar p21 (* (/ pi 2.0) 3.0) h)))
   (ssadd (entlast) ss)
 )
 (if inrec (entdel inrec))
 (vl-cmdf "_.pedit" "" "l" "y" "j" ss "" "")
 (setvar 'osmode osm)
 (princ)
)

(prompt "\nInvoke with : heat-spiral-2")
(princ)

Regards, M.R.

Thank you for your thanks to all participants in this challenge...

Edited by marko_ribar
Posted

 
(defun C:fh(/ centx cnt d1 d2 dx dy lp n nxt osm p1 p2 p3 p4 pt1 pt2 pt3 pt4
........... 

 

This seemed like a fun challenge, so I thought I might participate...

Here is my version:....

 

(defun makearc ( cen rad ang1 ang2 )

 

So many ways to skin a cat. :)

 

Great codes .. great minds :thumbsup:

 

EDIT: it made me think of a "cool' puzzle challenge.

Posted (edited)

Or try this one :

 

(defun makearc ( cen rad ang1 ang2 )
 (entmakex 
   (list
     '(0 . "ARC")
     '(100 . "AcDbEntity")
     '(100 . "AcDbCircle")
     (cons 10 cen)
     (cons 40 rad)
     '(100 . "AcDbArc")
     '(210 0.0 0.0 1.0)
     (cons 50 ang1)
     (cons 51 ang2)
   )
 )
)

(defun makeline ( p1 p2 )
 (entmakex
   (list 
     '(0 . "LINE")
     '(100 . "AcDbEntity")
     (cons 10 p1)
     (cons 11 p2)
     '(210 0.0 0.0 1.0)
   )
 )
)

(defun c:heat-spiral-3 ( / CEN1 CEN2 CEN3 CEN4 D DD H INREC K N OSM P1 P2 P3 P5 P6 P7 PST1 PST2 PTLST PTLSTN RAD REC SS Z )
 (setq osm (getvar 'osmode))
 (setvar 'osmode 0)
 (setq ss (ssadd))
 (setq rec (car (entsel "\nPick rectangle parallel to WCS axises with smaller side parallel to X axis")))
 (setq ptlst (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= (car x) 10)) (entget rec))))
 (setq d (distance (car ptlst) (cadr ptlst)))
 (initget 7)
 (setq k (getint "\nInput level of spiral turns (1,2,3,...) : "))
 (setq n (* k 2))
 (setq dd (/ d (float n)))
 (setq rad (/ dd 2.0))
 (if (/= k 1)
   (progn
     (vl-cmdf "_.offset" (* dd (float (- k 1))) rec (mapcar '(lambda ( a b c d ) (/ (+ a b c d) 4.0)) (car ptlst) (cadr ptlst) (caddr ptlst) (cadddr ptlst)) "")
     (setq ptlstn (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= (car x) 10)) (entget (setq inrec (entlast))))))
   )
 )
 (if (not ptlstn) (setq ptlstn ptlst))
 (setq pst1 (polar (polar (car ptlstn) 0.0 dd) (/ pi 2.0) rad))
 (setq pst2 (polar pst1 (/ pi 2.0) (- (setq h (distance (cadr ptlstn) (caddr ptlstn))) dd)))
 (makeline pst1 pst2)
 (ssadd (entlast) ss)
 (setq z -1.0)
 (repeat k
   (setq z (1+ z))
   (if (/= z 0.0) (setq h (+ h (* 2.0 dd))))
   (makearc (setq cen1 (polar pst1 0.0 rad)) rad pi (* (/ pi 2.0) 3.0))
   (ssadd (entlast) ss)
   (setq p1 (polar cen1 (* (/ pi 2.0) 3.0) rad))
   (setq p2 (polar p1 0.0 (* (* (float z) 2.0) dd)))
   (if (/= z 0.0)
     (progn
       (makeline p1 p2)
       (ssadd (entlast) ss)
     )
   )
   (makearc (setq cen2 (polar p2 (/ pi 2.0) rad)) rad (* (/ pi 2.0) 3.0) 0.0)
   (ssadd (entlast) ss)
   (makeline (setq p3 (polar cen2 0.0 rad)) (setq pst2 (polar p3 (/ pi 2.0) h)))
   (ssadd (entlast) ss)
   
   (setq pst2 (mapcar '+ pst2 (list (- dd) (- dd))))
   
   (makearc (setq cen3 (polar pst2 pi rad)) rad 0.0 (/ pi 2.0))
   (ssadd (entlast) ss)
   (setq p5 (polar cen3 (/ pi 2.0) rad))
   (setq p6 (polar p5 pi (* (* (float z) 2.0) dd)))
   (if (/= z 0.0)
     (progn
       (makeline p5 p6)
       (ssadd (entlast) ss)
     )
   )
   (makearc (setq cen4 (polar p6 (* (/ pi 2.0) 3.0) rad)) rad (/ pi 2.0) pi)
   (ssadd (entlast) ss)
   (makeline (setq p7 (polar cen4 pi rad)) (setq pst1 (polar p7 (* (/ pi 2.0) 3.0) h)))
   (ssadd (entlast) ss)
   
 )
 (if inrec (entdel inrec))
 (vl-cmdf "_.pedit" "" "l" "y" "j" ss "" "")
 (setvar 'osmode osm)
 (princ)
)

(prompt "\nInvoke with : heat-spiral-3")
(princ)

M.R.

Edited by marko_ribar
Posted

Look into this example... This scheme was produced from my last routine... Firstly draw rectangle, then offset it for a distance the pipes will be away from the walls... Then divide that new rectangle into 4 smaller ones, and apply my code on one of them - lower left one... Then erase 4 rectangles and just mirror newly created polyline make sure that horizontal mirror around y axis be at half distance between pipes... Then make arc for upper right corner, and place it at the end pipe of upper right mirrored polyline... Do the same for upper left arc, and at the end draw line from one arc to the other... You should get what is shown in the picture... I suggest this for larger rooms where length of pipes is limited... As you can see, you'll get 2 ends from pipes at the bottom of the room - one with warm matter supply and the other with cold matter drainage...

 

M.R.

HEATING SCHEME.jpg

Posted

Here is and 4th variant - similar to 1st and 2nd... Inside rectangle is made from odd number derived from turns similar to 1st code, and arcs are similar to 2nd code... So it is applicable to round rooms, like 2nd code...

 

(defun makearc ( cen rad ang1 ang2 )
 (entmakex 
   (list
     '(0 . "ARC")
     '(100 . "AcDbEntity")
     '(100 . "AcDbCircle")
     (cons 10 cen)
     (cons 40 rad)
     '(100 . "AcDbArc")
     '(210 0.0 0.0 1.0)
     (cons 50 ang1)
     (cons 51 ang2)
   )
 )
)

(defun makeline ( p1 p2 )
 (entmakex
   (list 
     '(0 . "LINE")
     '(100 . "AcDbEntity")
     (cons 10 p1)
     (cons 11 p2)
     '(210 0.0 0.0 1.0)
   )
 )
)

(defun c:heat-spiral-4 ( / CEN1 CEN2 D DD H INREC K N OSM P1 P2 PST1 PST2 PTLST PTLSTN RAD REC SS Z )
 (setq osm (getvar 'osmode))
 (setvar 'osmode 0)
 (setq ss (ssadd))
 (setq rec (car (entsel "\nPick rectangle parallel to WCS axises with smaller side parallel to X axis")))
 (setq ptlst (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= (car x) 10)) (entget rec))))
 (setq d (distance (car ptlst) (cadr ptlst)))
 (initget 7)
 (setq k (getint "\nInput level of spiral turns (1,2,3,...) : "))
 (setq n (+ (* k 2) 1))
 (setq dd (/ d (float n)))
 (setq rad (/ dd 2.0))
 (vl-cmdf "_.offset" (* dd (float k)) rec (mapcar '(lambda ( a b c d ) (/ (+ a b c d) 4.0)) (car ptlst) (cadr ptlst) (caddr ptlst) (cadddr ptlst)) "")
 (setq ptlstn (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= (car x) 10)) (entget (setq inrec (entlast))))))
 (if (not ptlstn) (setq ptlstn ptlst))
 (setq h (- (distance (cadr ptlstn) (caddr ptlstn)) dd))
 (setq pst1 (polar (cadr ptlstn) (/ pi 2.0) rad))
 (setq pst2 (polar pst1 (/ pi 2.0) h))
 (makeline pst1 pst2)
 (ssadd (entlast) ss)
 (setq z -1.0)
 (repeat k
   (setq z (1+ z))
   
   (makearc (setq cen2 (polar pst2 pi (+ (* (float z) dd) rad))) (+ (* (float z) dd) rad) 0.0 pi)
   (ssadd (entlast) ss)
   (makeline (setq p1 (polar cen2 pi (+ (* (float z) dd) rad))) (setq pst1 (polar p1 (* (/ pi 2.0) 3.0) h)))
   (ssadd (entlast) ss)

   (setq pst1 (mapcar '+ pst1 (list dd 0.0)))
   
   (makearc (setq cen1 (polar pst1 0.0 (+ (* (float z) dd) rad))) (+ (* (float z) dd) rad) pi (* pi 2.0))
   (ssadd (entlast) ss)
   (makeline (setq p2 (polar cen1 0.0 (+ (* (float z) dd) rad))) (setq pst2 (polar p2 (/ pi 2.0) h)))
   (ssadd (entlast) ss)
 )
 (if inrec (entdel inrec))
 (vl-cmdf "_.pedit" "" "l" "y" "j" ss "" "")
 (setvar 'osmode osm)
 (princ)
)

(prompt "\nInvoke with : heat-spiral-4")
(princ)

 

BTW. I've updated all 4 codes to make just 1 offset and h is calculated from that...

 

M.R.

Posted

This is a combination of 1st code and 4th code... 1st and 4th are compatible and 2nd and 3rd also...

 

See picture, you can now quickly make this pattern if one side of room is round...

 

M.R.

HEATING - 1+4.jpg

Posted

Some programs are good however you have a problem in the middle of the spiral it should be twice the distance between pipes

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