Jump to content
  • entries
    33
  • comments
    78
  • views
    61,918

Art via Programming: Circles


ubikuberalles

1,003 views

So far, the basic algorithms of the art generating programs I've presented were in the following form:

 

for i = 1 to SomeNumber
for j = 1 to SomeOtherNumber
	Determine StartPoint;
	Determine EndPoint;
	Draw a line or fill the region between StartPoint and EndPoint;
next j
next i

My latest program, circles has a different basic algorithm:

 

for i = 1 to StageWidth
for j = 1 to StageHeight
	DetermineColorToPlot(i,j);

	SetPixel(i,j)
next j
next i

 

Looks like a simple algorithm, but those looks can be deceiving. It's that DetermineColorToPlot subroutine that can be a source of all sorts of headaches. Sometimes the routine holds a simple sine wave equation or it just reads data from a file. Other times it's much more complex: computing partial derivatives, Laplace's equation or quadratic equations. Fractals are displayed using this basic algorithm with the DetermineColorToPlotsubroutine incorporating another loop that recalculates an equation until some pretermined end condition is met.

 

For my first attempt at this new algorithm, I decided to do something basic: the radius of a circle (x^2 + y^2). As I expected, I got a bunch of concentric circles. Pretty boring. So I tweeked the equation until I got this:

color = (((j - 200.0) / 200.0)^2 / 200 + ((i - 200.0) / 200.0)^2) / 2^n

Where n is a number I entered myself. I first tried the program with n = 0 and the results were remarkable:

 

circles00.jpg

 

Wow. Totally unexpected. It got better when I increased the value of n. Here's circles with n = 2:

 

circles02.jpg

 

n = 4:

 

circles04.jpg

 

n = 7:

 

circles07.jpg

 

And n = 10:

 

circles10.jpg

 

 

Before too long I made a movie of the results:

 

circles.gif

 

I thought I was done with the program until I realized I forgot about values of n that are less than zero. Here's what I got with n = -40:

 

circles-40.jpg

 

And n = -48:

 

circles-48.jpg

 

Both images reminded me of the sand paintings made by Tibetan monks or Navajo Indians.

 

Before long I figured out the limits of the program. The screen goes totally black with n = -65 and lower or n = 21 and higher. I also quickly created an animation and I was pleased by the results. It reminded me of the big bang. The problem with the animation was it incorporated over 90 frames and my first animation was over 4 Megabytes in size! So you have several options to view the movie:

 

Big Bang - tiny (150 X 150 - 504 Kb)

Big Bang - medium (200 X 200 - 994 Kb)

Big Bang - big (400 X 400 - 4624 Kb)

 

Circles was created with Flash 8 Professional and you can run the program yourself (as long as you have the latest Flash player - version 8 or later). Here it is. The program itself isn't very big (64 Kb or so) but it does suck up a great deal of CPU for a short period of time. On my laptop (a 1.6 GHz Sempron) it takes about 15 or 20 seconds to produce the graphic. Give it a try and let me know what you think.

 

EDIT: Here's a new version of the program. Slightly different controls and a new control that allow you to select different equations. For more info, see my comments for this post.

6 Comments


Recommended Comments

Unless your screen is many thousands of pixels on a side, I don't see any benefit to pre-dividing your coordinates by 200 before dividing them by the scaling factor.

 

Out of curiosity, have you tried x*y as a generating function yet?

Link to comment

The division was an artifact of the original equation for those concentric circles I mentioned earlier (IIRC it was to normalize the values to 1). When I first read your comment, I agreed. "Why are they there?" I asked. I had no answer so I removed them. The results were different and not near as interesting as the original (the sand painting structures disappeared). In fact, you have to set the power factor to at least 2 or 3 before you see anything interesting.

 

I've upgraded the program to include my original equation and the new equation. Here is the new program. On the right is a selector tool where you select what equation you want used. Equation 1 is the original and Equation 2 is with the division removed.

 

Until today I hadn't tried the X * Y equation. I have now included it in the version of the program I just posted (it's equation 3). Interesting structures from that equation: asymptotic curves. However, once again you won't see anything interesting until the power value is 2 or higher.

 

This recent work on the program has made it clear that I need to include controls that allow me to change the offset I built into the equation (the -200 in the (i-200) and (j-200) parts of the equation). I'll be doing that next (I'm running out of room at the bottom of the stage). Since the power function is acting like a zoom, I should rename that control.

Link to comment
The division was an artifact of the original equation for those concentric circles I mentioned earlier (IIRC it was to normalize the values to 1). When I first read your comment, I agreed. "Why are they there?" I asked. I had no answer so I removed them. The results were different and not near as interesting as the original (the sand painting structures disappeared). In fact, you have to set the power factor to at least 2 or 3 before you see anything interesting.

 

Hmm... looking back at your original formula it appears you're using X and Y differently, though I can't tell exactly what you're doing since you have unbalanced parentheses.

 

Obviously if you don't divide down the values in the earlier stages, they'll be much bigger in later stages, so a higher exponent value would be appropriate. Have you tried any fractional ones yet?

Link to comment

Oops. Big ol' typo in the equation. Fixed it.

 

Here's the equation straight from the program:

 

Radius = (Math.pow((j - 200) / 200.0,2.0) + Math.pow((i - 200) / 200.0, 2.0)) / Math.pow(2.0,parseFloat(Power.value,10));

 

And the second equation (the one where I removed the extraneous divisions):

 

Radius = (Math.pow(j - 200,2.0) + Math.pow(i - 200, 2.0)) / Math.pow(2.0,parseFloat(Power.value,10));

 

j is the inner loop variable and so it's plotted as the x value and i as the y value.

 

Oh ya, one more thiing. Since the numerator of the first equation held values between 0 and 1, that meant the Radius variable always had a value less than one (unless the power factor was 0). To normalize the color value to fit in the 24 bit color scheme, I multiplied Radius by 2^24:

 

ColorValue = Math.floor(Radius * Math.pow(2,24));

 

So, I guess the answer to your original question about why I divided by 200 is that I wanted to normalize the value to a small value (less than 2). This is so I could stretch it in a controlled manner to fit the colorspace (whatever that means :)). Again I think it was an artifact of the first concentric circles program I wrote (it's been a while - I can't remember exactly). They were probably put there because my first attempt didn't produce results (big black square) and I was trying to figure out what was wrong.

 

Fractional exponents? (Me leaves to take a look) Damn, my current program won't allow it. I'll have to modify the program. Sounds like my next modification to the program

Link to comment
Fractional exponents? (Me leaves to take a look) Damn, my current program won't allow it. I'll have to modify the program. Sounds like my next modification to the program

 

x^y = exp(log(x)*y) [where log(x) is the natural logarithm]

 

Note that for this formula to work, x must be non-negative but y may be anything. For computing the squares in your formula, the exp(log()) formula isn't as good as simply multiplying a number by itself.

 

Also, there's no need to compute 2^scalepower within your loop. Better to compute it outside the loop or, for that matter, just type in the exponentiated scale power you want.

Link to comment
Fractional exponents? (Me leaves to take a look) Damn, my current program won't allow it. I'll have to modify the program. Sounds like my next modification to the program

 

x^y = exp(log(x)*y) [where log(x) is the natural logarithm]

 

Note that for this formula to work, x must be non-negative but y may be anything. For computing the squares in your formula, the exp(log()) formula isn't as good as simply multiplying a number by itself.

I obviously misunderstood your original comment. By "fractional exponents" I thought you meant setting the "Power Factor" number to a value less than 1. I did change the program to set Power Factor to a non-integer result and, although some of the Power Facor settings were interesting, the results were not too different from the Integer values of the number.

 

No, I haven't tried the above equation yet. I have tried log|x| - log|y| and I've gotten interesting results. The only real problem with using logorithms in my program is not negative values of x (I just use the abs function) but for when x = 0. I arbitrarly set log(0) to 0. It was either that or set it to 1 (in the case of x = 0, I could just skip to the next iteration of the loop but that's essentially the same as setting the equation to 0).

 

Using x^y is problematical (get it?) since there are many boundary conditions. Making log(0) = 0 is easy but it won't be long in the loop before the calculations cause an overflow error. I don't know what the largest number Actionscript can compute (10^308 is my guess) but I know for sure the program will fail long before it calculates 200^200 (Which comes to, approx. e^1060. That's a big number!). I still haven't figured out how to implement x^y yet but, most likely it would most likely be in the form: ((x - 200) / 200)^((y - 200)/200) to keep the values between 0 and 1. I'll have to experiment before I will be able to figure it out.

 

Also, there's no need to compute 2^scalepower within your loop. Better to compute it outside the loop or, for that matter, just type in the exponentiated scale power you want.

I saw that and moved the computation outside the loop. I also moved the computation of Y^2 outside the X loop. These modifications did improve performance but, alas, not significantly.

 

With all these new equations in the program, calling the program Circles no longer makes sense. So I moved the original version of Circles to the completed folder and renamed the new version to Equations. Once I have enough equations in the program, I'll post it in my blog.

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  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.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...