Hi, I'm trying to define a grid based on polar coordinates.
Can be produced using the following MATLAB code:
n=1:50000; r=sqrt(n); t=360/((sqrt(5)+1)/2)+1)*pi/180*n; plot(r.*cos(t),r.*sin(t),'o')
I need to insert points based on the polar coordinates defined by the equations.
I knew a little bit of LISP 10 Years ago, now it's a total blank. I've been trying to write a script to make this work but after 5 days I'm still without sucess.
Can someone help?
Can you please explain a little bit more of what you are trying to have in steps ?
Regards.
Tharwat
Thank you very much for the reply!
The grid I'm trying to make is the application of the Vogel's Formula. I'm attaching an image for visualization.
I'm going to try to explain what I'm trying to do step by step.
I think this is completely wrong but I hope that I'll be able to explain myself with this.
n= is the list number of points from 1 to 50000
r= sqtr n - it's the distance between the starting point and the point that is being placed
t= 360/((sqrt(5)+1)/2)+1)*pi/180*n - it's the rotation angle
360/((sqrt(5)+1)/2)+1) can be aprox. 137.5077 (the golden angle)
the starting point will be ( 0, 0, 0) so that the distance number 1 is 1
I was trying to define the Lisp like this:
(defun c:points ( )
(setq n (list (1 ... 50000)) ;; Number of points
(setq r sqtr (n )) ;; Distance
(setq t (360/((sqrt(5)+1)/2)+1)*pi/180*n) ;; Rotation angle
(princ "\nGrid")
(command "point"
(append
(list (cons 10 ( r*cos(t), r*sin(t), 0))))))
(princ)
)
Thank you very much in advance.
Best regards.
@user758 wrote:....
The grid I'm trying to make is the application of the Vogel's Formula. I'm attaching an image for visualization.
....
If I'm interpreting your equation construction correctly, and if I may do some lowest-common-denominator trimming, I think this does that:
(defun C:Vogel (/ n)
(setq n 0)
(repeat 500;;;;;;;<---I didn't go all the way to 50,000....
(entmake
(list
'(0 . "POINT")
(cons
10
(polar
'(0 0 0); point
(/; angle
(* 2 pi (setq n (1+ n)))
(1+ (/ (1+ (sqrt 5)) 2))
); end /
(sqrt n); distance
); end polar
); end cons
); end list
); end entmake
); end repeat
); end defun
It could also be made to ask the User how many points they want.
EDIT: If your angle represents degrees, you might need to revise that, because (polar) works in radians. At least what the above does looks like your image, but it may not be correct yet. But your having a multiplication by pi and division by 180 in your formula makes me wonder whether it really already represents radians, and not degrees, in which case the above should be fine.
Well done Kent, this is brilliant!
I have been searching for this on Google for weeks, seriously considered learning how to write lisp routines and making it myself. I should have come here first.
If it's not too much trouble, is there a way I can substitute a block in for the point and/or number each one sequentially?
FYI:
I'll be using it to set out locations for testing on a large project with potential contamination. Typical grid systems such as square or hexagonal wont do it, because if there's a linear deposit of contamination (eg from a leaky pipeline or extinct river bed) then it might get missed. Random testing won't do it because each test is expensive and needs to be placed carefully. Tests need to be evenly spaced, but still random / non linear. I'll also be using it to make colouring in patterns for the kids!
Just some key words to make it more visible for other people searching: Sunflower, Fibonacci, Phi, Golden Ratio, Spiral, Vogel, Fermat, seed close packing, optimal packing, sample spacing, irregular grid, flower lisp routine, irrational angle, testing, soil testing, borehole, CPT
@Anonymous wrote:Well done Kent, this is brilliant!
.... is there a way I can substitute a block in for the point and/or number each one sequentially?
....
Thank you! It was just a translation of the formula in the appropriate AutoLISP syntax.
Placing Blocks is the easy part. You just need the Insert object type and the Block name, if you don't mind their all being at scale factors of 1 and rotation of 0 and on the current Layer:
(defun C:Vogel (/ n)
(setq n 0)
(repeat 500;;;;;;;<---YOUR QUANTITY
(entmake
(list
'(0 . "INSERT")
'(2 . "YOURBLOCKNAME");;;;;;;<--- edit this
(cons
10
(polar
'(0 0 0); point
(/; angle
(* 2 pi (setq n (1+ n)))
(1+ (/ (1+ (sqrt 5)) 2))
); end /
(sqrt n); distance
); end polar
); end cons
); end list
); end entmake
); end repeat
); end defun
If you want scales and/or rotation, Layer, etc., those are easy enough to add into the (enmake) list.
If you don't always want to use the same block and/or quantity, you can make a function with arguments:
(defun Vogel (blk num / n)
(setq n 0)
(repeat num
(entmake
(list
'(0 . "INSERT")
(cons 2 blk)
;.... the rest the same....
which you would use like this, typing in [including the parentheses]:
(Vogel "YourBlockName" YourQuantity)
e.g.
(Vogel "BlockABC" 750)
Or it could be built as a command that would prompt the User for the Block name and quantity [and scale and rotation and...]. And you could build in [or ask the User for] a multiplier of some kind for spacing, a center point, and I'm sure some other things.
For numbering, that can certainly be done, too -- are you talking about assigning sequential numerical values to an Attribute in a Block, or placing sequential Text entities, or....?
I wondered what would happen if you took the square root of something other than 5. Interesting effects [see drawing], but Vogel seems to have gotten it "right" for something that looks most like the pattern of sunflower seeds, etc.
That's a really interesting dwg, thanks for posting!
If you're interested, there's a specific reason why 1/2+sqrt(5)/2 is used, it's the golden ratio. It is frequently found in nature, in almost everything. Just a few examples:
I could go on indefinitely about the subject, and many people have spent years dedicated to nothing else. It has been known about for thousands of years, since the parthenon was built using the golden proportions, and it is even evident in the spirals of galaxies.
Well worth investigating further, if you have the time.
Also, just to show my appreciation again for your efforts, here's a slight modification I did where you can specifiy the insertion point and the number of points you want. I copied from an existing lisp routine I had. Works fine unless you have a custom ucs.
(defun C:Vogel (/ n)
(setq n 0)
(setq ip (getpoint "\nInsertion point for sunflower array: "))
(princ ip)
(setq nump (getint "\nNumber of points: "))
(repeat nump;;;;;;;<---I didn't go all the way to 50,000....
(entmake
(list
'(0 . "POINT")
(cons
10
(polar
ip ; point
(/; angle
(* 2 pi (setq n (1+ n)))
(1+ (/ (1+ (sqrt 5)) 2))
); end /
(sqrt n); distance
); end polar
); end cons
); end list
); end entmake
); end repeat
); end defun