
I don't quite get it....
I was wondering if any of the "mathminded" individuals here could shed some light on this for me. I read this article:<BR>http://eurologo.web.elte.hu/lectures/intrins.htm<BR>An cooked up some code based upon what I read. Here is the main function of my code:<BR><BR>[code language="C#"]<BR>private void involute(double t)<BR>{<BR> double a = 0.0025;<BR> if(t < 600) <BR> {<BR> a = a * t;<BR> double x = a * (Math.Cos(t) + t * Math.Sin(t));<BR> double y = a * (Math.Sin(t)  t * Math.Cos(t));<BR> GraphicsPath myPath = new GraphicsPath(); <BR> myPath.AddEllipse(float.Parse((x+this.m_xOffset).T oString()), float.Parse((y+this.m_yOffSet).ToString()), this.m_orbSize.Width, this.m_orbSize.Height); <BR> PathGradientBrush orbBrush = new PathGradientBrush(myPath); <BR> if(this.counter % 2 == 0)<BR> orbBrush.CenterColor = Color.Yellow; <BR> else<BR> orbBrush.CenterColor = Color.Gold;<BR> Color[] arrColor = new Color[1] {Color.Black}; <BR> orbBrush.SurroundColors = arrColor; <BR> this.m_graphics.FillEllipse(orbBrush, float.Parse((x+this.m_xOffset).ToString()), float.Parse((y+this.m_yOffSet).ToString()), this.m_orbSize.Width, this.m_orbSize.Height);<BR> this.m_graphics.DrawEllipse(new Pen(Brushes.Black, 3f), float.Parse((x+this.m_xOffset).ToString()), float.Parse((y+this.m_yOffSet).ToString()), this.m_orbSize.Width, this.m_orbSize.Height);<BR> t+=.618;<BR> this.m_orbSize.Height += 0.125f;<BR> this.m_orbSize.Width = this.m_orbSize.Height;<BR> counter++;<BR> involute(t);<BR> }<BR>}<BR>[/code]<BR><BR>The image generated by the code can be seen here: http://www7.brinkster.com/christophern/images/Spirals.jpg<BR><BR>I do not quite understand how the code works. I have some control over the output by changing one of two variables, but I would really like to understand all of it in detail. Can anyone explain it or point me to some reading that would help? What should I be studying? Geometry, Trigonometry and Calculus? Thanks.

RE: Stupid Brinkster....
I can't link to the pic directly, let me wrap some html around it and see if that works... BRB....

RE: Try This
http://www7.brinkster.com/christophern/spirals.htm

Well, just strip it down...
...to only the math code:<BR><BR>private void involute(double t) <BR>{ <BR> double a = 0.0025; <BR> if(t < 600) <BR> { <BR> a = a * t; <BR> double x = a * (Math.Cos(t) + t * Math.Sin(t)); <BR> double y = a * (Math.Sin(t)  t * Math.Cos(t)); <BR> // draw a shaded circle at x,y position<BR> t+=.618; <BR> involute(t); <BR> } <BR>} <BR><BR>So it's just doing recursion, creating one circle at a time along the spiral path. Just dump out the successive values of t and x and y to see what is happening numerically.<BR><BR>I don't see why it needs to use recursion, though. <BR><BR>Seems to me you accomplish the same thing without it:<BR><BR>private void involute(double t) <BR>{ <BR> double a = 0.0025; <BR> for ( ; t < 600; t += 0.618 )<BR> { <BR> a = a * t; <BR> double x = a * (Math.Cos(t) + t * Math.Sin(t)); <BR> double y = a * (Math.Sin(t)  t * Math.Cos(t)); <BR> // draw a shaded circle at x,y position<BR> } <BR>} <BR><BR>You can check me to see if I'm right.<BR><BR>There is some *REALLY* funky code in there!<BR><BR>This is really weird:<BR> float.Parse((x+this.m_xOffset).ToString())<BR>HUH? ?<BR><BR>We already know that x is declared as double. <BR><BR>If this.m_xOffset is declared as double (or even as integer), then the result of adding them is going to be a double number. <BR><BR>But then this code converts the result of the addition (a double number) to a STRING (using .ToString) and then converts that string *BACK* to a double using float.Parse !!!<BR><BR>WHAT IS THE POSSIBLE POINT OF THAT???<BR><BR>If you stop using recursion (assuming my transformation to a for loop works), then there are several optimizations that can be made here.<BR><BR>

How about this?
private void involute(double t) <BR>{ <BR> GraphicsPath myPath = new GraphicsPath(); <BR> Pen ppen = new Pen(Brushes.Black, 3f);<BR> int which = 0;<BR> Color[] blackColor = new Color[1] {Color.Black}; <BR> Color[] centerColors = new Color[1] {Color.Yellow, Color.Gold}; <BR><BR> for ( ; t < 600; t += 0.618 )<BR> { <BR> double a = 0.0025 * t; <BR> double px = this.m_xOffset + a * (Math.Cos(t) + t * Math.Sin(t))<BR> double py = this.m_yOffSet + a * (Math.Sin(t)  t * Math.Cos(t));<BR><BR> myPath.AddEllipse( px, py, this.m_orbSize.Width, this.m_orbSize.Height); <BR> // not sure if this can be moved before "for" or not...probably could be<BR> PathGradientBrush orbBrush = new PathGradientBrush(myPath); <BR> orbBrush.CenterColor = centerColors[which];<BR> which = 1  which;<BR> orbBrush.SurroundColors = blackColor; <BR> this.m_graphics.FillEllipse(orbBrush, px, py, this.m_orbSize.Width, this.m_orbSize.Height); <BR> this.m_graphics.DrawEllipse(ppen, px, py, this.m_orbSize.Width, this.m_orbSize.Height); <BR> this.m_orbSize.Height += 0.125f; <BR> // why have separate variables for Height and Width if they have same values???<BR> // why not just have one variable named "Size" and use it for both?<BR> this.m_orbSize.Width = this.m_orbSize.Height; <BR> } <BR>} <BR>

I tried it for you...worked...
With one minor change:<BR><BR>private void involute(double t) <BR>{ <BR> for ( ; t < 600; t += 0.618 ) <BR> { <BR> double a = 0.0025 * t; <BR> double x = a * (Math.Cos(t) + t * Math.Sin(t)); <BR> double y = a * (Math.Sin(t)  t * Math.Cos(t)); <BR> // draw a shaded circle at x,y position <BR> } <BR>} <BR><BR>Had to move the declaration of a, else it was cumulative each time through loop. Oops.<BR><BR>No idea why the original author thought recursion was needed for this! In some languages, the stack size would limit the usefulness of the recursion, such that you'd run out of stack after too few ellipses (balls).<BR><BR>

Okay, went and read the article...
The author was using turtle graphics. Code similar to what one would use in the LOGO language. <BR><BR>And since he is using "tail recursion" (that is, the recursive call occurs as the last thing in the function), it's easy for LOGO to optimize that so that no *actual* recursion (use of the stack) occurs. So it really does become just a loop.<BR><BR>And the author *DOES* explain why it works:<BR><BR>The procedure Involute has the same structure as the classic procedure [1] in turtle graphics  POLYSPI (for constant value, like 1, of the parameter ANGLE):<BR><BR>to POLYSPI :ANGLE :SIDE<BR>if (:SIDE > 70) [stop]<BR>right :ANGLE forward :SIDE<BR>POLYSPI :ANGLE (:SIDE + 1)<BR>end<BR><BR>For large angles, like ANGLE = 60, this procedure draws polygon Spirals (Fig.4.2). For small turn angles, like ANGLE = 1, and progression in infinitesimal steps, like :SIDE / 1000, POLYSPI represents a mathematical curve  [b]the Involute of a circle[b].<BR><BR>SO it's just an approximation of an involuted circle, or an approximation of a spiral.

Minor goof there...
Color[] centerColors = new Color[[hl]2[/hl]] {Color.Yellow, Color.Gold};

Grumble...try again:
Color[] centerColors = new Color[[hl="pink"]2[/hl]] {Color.Yellow, Color.Gold};

RE: I don't quite get it....
Bill, <BR><BR>Thanks for your time. I phrased my question wrong. I understand the code (syntactically), but I am missing the understanding of the two equations (semantically):<BR>double x = a * (Math.Cos(t) + t * Math.Sin(t));<BR>double y = a * (Math.Sin(t)  t * Math.Cos(t));<BR><BR>Yes, those are the equations that yeild the coordinates that will describe the curve, but [b]WHY[]? That is what I want to understand. What should I be reading to get a better feel for these concepts?<BR><BR>I know the code was sloppy: that was the first draft, written as I thought it. I did not go back and optimize/correct it yet. Since you have already done this for me, I will try your version when I get home.<BR>
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

