Calculating the periodicity of a rose curve

I'm having fun generating pretty pictures using math, and have started to draw rose curves. Thing is, I'm not sure when to stop drawing.

The formula is the same as from the wikipedia entry - a=angle, $k=n/d$, $r\cos(k*a)$, $x=r\cos a$, $y=r\sin a$. I'm working in degrees, so $a=0 to 359$, but that doesn't close all the curves, and only half of some...

I've read that periodicity is either $\pi d$ radians or $2\pi d$ radians, and the most accurate I've found so far is that if $n$ and $d$ are relatively prime, and both $n$ and $d$ are odd then it's $\pi d$ radians else $2\pi d$ radians. However, when testing I'm finding that's not the case.

For example, I store the first point and increase a until I get back to the first point's coordinates. I then print $n$,$d$ and final $a$ to the screen ($a$ is in degrees):

$(1,1) = 180$

$(1,2) = 720$

$(1,3) = 540$

$(1,4) = 1440$

$(1,5) = 900$

$(1,6) = 2160$

$(1,7) = 1260$

etc. I'm finding $n$ and $d$'s co-prime status by taking the GCD of $n$ and $d$ (I've also tried GCD$(n-1,d-1)$ to no avail). If it's $1$, and both $n$ and $d$ are odd, I then assume $\pi d$ radians else $2\pi d$ radians. The sequence matches my results above only for even values of $d$, and then only for certain values of $n$... I've tried allsorts of other methods and I'm afraid I'm just not getting it.

Is the original method I use (watching for a repeat of the first coordinate) the only way to accurately predict how many degrees it takes to start the next period?

Many thanks.

• Thanks for the edit - I'm new here. Just one thing I noticed - angle a goes from 0 to 359 in "I'm working in degrees, so a=0..359" - sorry for the mistake, I usually write ranges as x..y, so it should read 0 to 359. It's been edited to a=0.359 which is quite different! Apologies for not making it clearer. – ZXDunny Oct 23 '15 at 12:42
• Ok, been doing some more investigations and I can calculate the periodicity for odd values of n very accurately, but even values have some odd rules that I have yet to figure out. For Odd values, I use: LET l=(LCM(n,d)*360/n)/2. Dividing by two when odd works perfectly. However, for even values it only works for odd values of n, and some evens. – ZXDunny Oct 23 '15 at 13:49
• There is a pattern to which even values of n that the above formula doesn't work. I calculated the intervals between values that fail, and the intervals follow the pattern 4,8,4,16, 4,8,4,32, 4,8,4,16, 4,8,4,64 and then repeats ad infinitum. for each interval, the sequence starts at in the interval divided by 2 - i.e, "4" starts at d=2, "8" starts at d=4, "16" starts at d=8 etc. All I need to do is determine from n which interval to use, and then divide the appropriate d values by 2 to get the correct value for any n/d combination. Anyone any ideas? – ZXDunny Oct 23 '15 at 13:57

I think I have it. Here's the BASIC code to draw all n=1 to 7, d=1 to 9 from the wikipedia entry:

10 REM Rose
20 DEGREES:
LET s=MIN(SCRw,SCRh)/2:
FOR n=1 TO 7:
FOR d=1 TO 9
30         LET l=LCM(n,d)*360/n,
np=2^(CEIL(LN n/LN 2)+1),
p=2:
DO:
IF n MOD p=p/2 AND d MOD p=p/2 THEN
LET l=l/2
ELSE
LET p=p*2: LOOP UNTIL p>np
40         LET k=n/d:
FOR a=0 TO l:
LET x=s*COS(k*a)*COS a,y=s*COS(k*a)*SIN a:
IF a=0 THEN
PLOT x+SCRw/2,y+SCRh/2
ELSE
DRAW TO x+SCRw/2,y+SCRh/2
50         NEXT a:
PAUSE 0:
CLS:
NEXT d:
NEXT n


It's pretty dense, so here's a quick explanation:

Line 20 sets up degrees mode, and the scaling (s) which is the smaller of the screen width or height. The loops for n and d start here.

Line 30 is the interesting part. First, calculate the lowest common multiple of n and d, then multiply by 360/n. This is the length of the curve in degrees. Then calculate the next highest power of two of n or d, whichever is greater.

Now, starting with the lowest even power of two (2) in p, test to see if both n modulus p is equal to p/2 and d modulus p is equal to p/2 - if so, then divide the length by two, and exit the loop to draw the curve. If not, then multiply p by 2 to get the next power of two, and test again until we pass the highest power of two to test (np).

Variable l now holds the length of the curve in degrees. I've tested for n in the range 1 to 1024 and d in the range 1 to 1024, and it works for those values. I suspect it doesn't work for non-integer values of n or d, but that's not something I need. I tested by drawing each curve for all values and comparing the number of degrees turned against the above calculation (as in my first post), which match exactly.

Lines 40 and 50 draw the curve, they're of no interest.

So I think I got there - if anyone can poke holes and suggest a better solution, I'm all ears!

• After discussion with a friend who is more mathematically minded than I am, he pointed out why I was having to use a looped algorithm to determine the correct length. After some testing, this is my final answer: '30 LET g=GCD(n,d),d1=d/g,l=180*d1*(EVEN(n/g*d1)+1)' which works perfectly - by going the LCM route previously, I was only completing half of the actual formula! – ZXDunny Dec 3 '15 at 0:58