TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: MP on December 10, 2008, 09:38:05 PM
-
Write a function that takes 2 arguments:
Arg 1: Radians (a value between 0 and 2*PI)
Arg 2: Sectors (an integer between 2 and 32)
Signature:
(defun GetSector ( radians sectors )
...
)
Objective:
Find where the value radians falls in a circle divided into sectors.
If the radians value corresponds exactly to a sector boundary return the whole
number that is equal to the lower sector it is adjacent to.
For any radian value that does not correspond to a sector boundary, return
the whole number that is equal to the lower sector it is adjacent to plus 0.5.
Sector numbers start at 1.
For example, given radian values of:
pi/8
pi/6
pi/4
pi/2
pi
And a sectors value of 4 ( boundaries on multiples of pi/2, or 90° ) the return values should be:
0.5
0.5
0.5
1.0
2.0
Using the same radian values but a sectors value of 5 ( boundaries on multiples of 2pi/5 or 72° ) the return values should be:
0.5
0.5
0.5
1.5
2.5
Using the same radian values but a sectors value of 6 ( boundaries on multiples of pi/3 or 60° ) the return values should be:
0.5
0.5
0.5
1.5
3.0
Perhaps an illustration of the first example will make it easier to understand than my pigeon engrish:
(http://www.theswamp.org/screens/mp/sectors.png)
A radians value of precisely 0 should return 0.
A radians value of precisely pi/2 should return 1.
Radians values between 0 and pi/2 should return 0.5.
Clear as mud? :D
Even someone with say a grossly verbose vertical coding style should be able to do it in a half dozen lines of code. :whistle:
Note: Assume the function will be passed valid data, i.e. you do not have to qualify the arguments -- just do the math.
-
.... half dozen lines of code
... depends on the formatting ... :)
but something like
(defun GetSector (radians sectors / segment)
(setq segment (/ radians (/ (* pi 2) sectors)))
(+ (fix segment)
(if (zerop (- (fix segment) segment)) 0.0 0.5 )
)
)
didn't have time to fully test or optimise ... lunch is over ... :|
edit: fixed the local variables ( / sloppy) ...
-
(GetSector (/ PI 8) 4 ) ;==>
(GetSector (/ PI 6) 4 ) ;==>
(GetSector (/ PI 4) 4 ) ;==>
(GetSector (/ PI 2) 4 ) ;==>
(GetSector (/ PI 1) 4 ) ;==>
(GetSector (/ PI 8) 5 ) ;==>
(GetSector (/ PI 6) 5 ) ;==>
(GetSector (/ PI 4) 5 ) ;==>
(GetSector (/ PI 2) 5 ) ;==>
(GetSector (/ PI 1) 5 ) ;==>
(GetSector (/ PI 8) 6 ) ;==>
(GetSector (/ PI 6) 6 ) ;==>
(GetSector (/ PI 4) 6 ) ;==>
(GetSector (/ PI 2) 6 ) ;==>
(GetSector (/ PI 1) 6 ) ;==>
0.5
0.5
0.5
1.0
2.0
0.5
0.5
0.5
1.5
2.5
0.5
0.5
0.5
1.5
3.0
-
(defun GetSector (rad sec / v)
(setq v (/ rad (/ (* PI 2.0) sec))))
(if (zerop (- (fix v) v))
(fix v)
(+ (fix v) 0.5))
)
Paul
-
Very cool you guys, similar to mine, if not more succinct:
When I first coded mine up it looked like this:
(defun _GetSector ( radians sectors )
( (lambda ( divisor )
(+ (if (zerop (rem radians divisor)) 0.0 0.5)
(fix (/ radians divisor))
)
)
(/ pi sectors 0.5)
)
)
But I found some boundary conditions didn't satisfy zerop properly, so I ended up with:
(defun _GetSector ( radians sectors )
( (lambda ( divisor )
(+ (if (equal 0.0 (rem radians divisor) 1e-8) 0.0 0.5)
(fix (/ radians divisor))
)
)
(/ pi sectors 0.5)
)
)
Funny thing is it took about 10 times longer to write the initial post than the function itself.
I always find it interesting how similar techniques are used but in different implementations, thanks for playing folks. :)
-
My eye sight goes fuzzy when I see lambda in lisp, along with the vla- stuff, but that
is a pretty cool use of rem.
Somehow I had an extra paren between copying and pasting my original, so here it is again, fixed,
and rearranged to get rid of a division.
(defun GetSector (rad sec / v)
(setq v (* rad (/ sec (* PI PI))))
(if (zerop (- (fix v) v))
(fix v)
(+ (fix v) 0.5))
)
-
What a minute MP, can you explain how the lambda is working in your
code? I'm not seeing it :ugly: :ugly:
Edit: I see it now, duh!
-
My eye sight goes fuzzy when I see lambda in lisp, along with the vla- stuff, but that
is a pretty cool use of rem.
Somehow I had an extra paren between copying and pasting my original, so here it is again, fixed,
and rearranged to get rid of a division.
(defun GetSector (rad sec / v)
(setq v (* rad (/ sec (* PI PI))))
(if (zerop (- (fix v) v))
(fix v)
(+ (fix v) 0.5))
)
Sorry for the use of lamba Paul, it just is cleaner to me than assigning then using, though admittedly more aesthetic than anything else.
Your function is close but not quite there ... (getsector pi 4) returns 1.5 whereas the correct answer is 2. :)
-
What a minute MP, can you explain how the lambda is working in your
code? I'm not seeing it :ugly: :ugly:
Edit: I see it now, duh!
I was just about to respond! Glad you got it. :)
-
NP. I wish I had learned lisp better way back when, but I just couldn't get into it at all.
As for the second function...it works on my system:
Command: (getsector (/ pi 1) 4)
2
Edit:
Command: (getsector pi 4)
2
Paul
-
Too late to the party so nothing much I can contribute.
I can rearrange the parts though.
(defun GetSector (rad sec / v)
(cond
((equal 0.0 (- (fix (setq v (/ rad (/ (* PI 2) sec)))) v) 1e-8)
(fix v))
((+ (fix v) 0.5))
)
)
Off to bed...Zzzzzzz 8-)
-
NP. I wish I had learned lisp better way back when, but I just couldn't get into it at all.
As for the second function...it works on my system:
Command: (getsector (/ pi 1) 4)
2
Edit:
Command: (getsector pi 4)
2
Paul
re: "Way back when ...". I remember when I had to pick up lisp way back, and did it under duress -- I thought it was butt ugly code, but my boss at the time pretty much forced me to pick it up. :D.
Are you sure you're testing the ones you posted? Both of them are returning 1.5 from (getsector pi 4), and I've reloaded them twice. :shrug:
-
Are you sure you're testing the ones you posted? Both of them are returning 1.5 from (getsector pi 4), and I've reloaded them twice. :shrug:
That second version is a bust, v is computed to the wrong value. The first version works if you remove the extra paren from
the second line so it reads (setq v (/ rad (/ (* PI 2.0) sec)))
re: "Way back when ...". I remember when I had to pick up lisp way back, and did it under duress -- I thought it was butt ugly code, but my boss at the time pretty much forced me to pick it up. :D.
R10 days, I think around 1990. I thought lisp was OK, but I had about 11 years of assembly language under my belt and was
determined to learn C and later ADS/ARX. So any lisp I learned was just enough to get a job done.
But, that being said, after all these years there are 2 books that I still use today
whenever I need help with lisp code. #1 "Maximizing AutoCAD: Inside Autolisp
Volume 2" and #2 (sorry Tony :kewl:) "Maximizing AutoCAD R13". Granted I haven't looked
at many custominzing books in a long time, but nothing beats those 2, IMO.
-
Hi,
My 2 cents, quite late but I was sleeping while you where playing.
(defun getsector (radians sectors / r f)
(if (equal (setq r (/ (* radians sectors 0.5) pi))
(setq f (fix r))
1e-8
)
f
(+ f 0.5)
)
)
-
That second version is a bust, v is computed to the wrong value. The first version works if you remove the extra paren from
the second line so it reads (setq v (/ rad (/ (* PI 2.0) sec)))
got ya
R10 days, I think around 1990. I thought lisp was OK, but I had about 11 years of assembly language under my belt and was
determined to learn C and later ADS/ARX. So any lisp I learned was just enough to get a job done.
But, that being said, after all these years there are 2 books that I still use today
whenever I need help with lisp code. #1 "Maximizing AutoCAD: Inside Autolisp
Volume 2" and #2 (sorry Tony :kewl:) "Maximizing AutoCAD R13". Granted I haven't looked
at many customizing books in a long time, but nothing beats those 2, IMO.
I hear ya. I first toyed with LISP around '86, wrote some tiny utilities but I was heavily embroiled in BASIC PDS and Turbo C at the time and could be bothered to really get into LISP. It was 1990 when my boss "encouraged" me to learn LISP (we had a GIS project that was failing because we were continually shipped LISP from another party, LISP that was crucial to project execution, that wouldn't work). To learn LISP I pretty much typed the entire (Autodesk supplied) LISP manual into a help file linked into my text editor so I had access to it as I coded.
-
Here is mine. Didn't look because I didn't want to write with a tainted mind, but it is pretty close to what is already here, if not exact. But a fun little exercise.
(defun FindSector ( rad sec / Sector)
(setq Sector (/ rad (/ (* 2 pi) sec)))
(if (equal (rem Sector 1) 0.0 0.000001)
Sector
(+ 0.5 (fix Sector))
)
)
-
Here is mine ...
Hi, My 2 cents ...
Thanks guys. Kinda scary how we all think along the same lines but implement slightly different. Thanks for sharing your interpretations of a solution. :)
-
(defun ragged_grey ()
(if liberators
(setq feel '(hope))
(setq feel '(fear))
)
)
Please disregard preceding post.
-
I shouldn't write post code in haste ... didn't even make my variables local.
on another issue : is nice to read a thread without social comment splattered throughout.
edit : oops, I just made a social comment.
-
... didn't even make my variables local.
Like you said, you knocked it out quick, I wasn't going to nit pick something you'd fix as soon as you returned to the thread.
-
(defun ragged_grey ()
(if liberators
(setq feel '(hope))
(setq feel '(fear))
)
)
Please disregard preceding post.
Close:
(setq feel
(if liberators
'(hope)
'(fear)
)
)