Authors: Joel and Michael Faber
Polar coordinates are an alternative to the more common rectangular coordinates that simplifies the math for many applications. In fact, about about a quarter of the many JWildfire variations are based on polar coordinates! Understanding them can help us use these variations more effectively.
Rectangular coordinates (also called Cartesian coordinates after their inventor René Descartes) identify the location of a point in two dimensional space using the distance from a special point, the origin, in two directions. The point (x, y) is x units to the right of the origin and y units up from the origin. We can visualize how they work by setting one element (x or y) to some constant value and drawing the curve created by letting the other element be any value. For rectangular coordinates, the curves will always be lines, as shown in this diagram:
For example, the line labeled “x=1” is a vertical line that contains all the points where x is 1 and y is between -2.5 and 2.5. The point (-0.5, 1.5) is located at the intersection of the vertical x=-0.5 line and the horizontal y=1.5 line. The origin (0,0) is at the intersection of the x=0 and y=0 lines.
Note that flame fractal programs, including JWildfire, flip the vertical axis, so the line y=1 is below the y=0 line (the x-axis), where the line y=-1 is shown above. The JWildfire interface compensates for this when moving the triangles, but it is important to know when you set the values on the Affine tab manually. As we shall see shortly, it is also important to know when using some variations.
Polar coordinates take a different approach: using distance and direction. The point (ρ, θ) is ρ units from the origin along a line that is at angle θ from the line extending horizontally right from the origin. (For those not familiar with Greek, ρ and θ are the greek letters rho and theta. Some people use r instead of ρ and ϕ (phi) or t instead of θ). A grid showing constant values of ρ and θ looks like this:
Constant values of ρ result in circles and constant values of θ result in lines with one end at the origin. For example, the curve ρ=2 contains all points at distance 2 from the origin: a circle. The curve θ=π contains all the points on a horizontal line left of the origin (here cut off at distance 3). The angle θ can be expressed in radians or degrees. Since the variations that deal directly with polar coordinates use radians, that’s what we use here. Since 180° equals π radians, we can easily convert from radians to degrees by multiplying by 180/π, and from degrees to radians by multiplying by π/180.
Unlike rectangular coordinates, there are multiple ways to express any point in polar coordinates. For example, all of the following represent the same point, ((0, -2) in rectangular coordinates).
- (2, -π/2): From the origin, go right 2 units, then go clockwise along the circle π/2 radians (one fourth of the way).
- (2, 3π/2): From the origin, go right 2 units, then go counter-clockwise along the circle 3π/2 radians (three fourths of the way).
- (2, -5π/2): From the origin, go right 2 units, then go clockwise along the circle 5π/2 radians (one full turn plus another fourth).
- (-2, π/2): From the origin, go left 2 units, then go counter-clockwise along the circle π/2 radians (one fourth of the way).
When we need a unique representation, such as when converting to polar coordinates, we restrict the possible values to ρ ≥ 0 and -π 0, and points less then one unit have ρ < 0. The angle θ is the same as polar coordinates. Here is a log-polar grid:
To see why this is useful, let’s look at tilings in the different coordinate systems, which is essentially placing a shape on each of the intersections of curves in a grid. In rectangular coordinates, tiling a disk simply repeats it horizontally and vertically.
This was done in JWildfire using a transform with blur to make the initial disk (at the center), and four transforms with linear to move the disk up, down, right, and left. More details are in the linear description.
For a polar tiling, we start with the disk shifted right to (1,0), and notice that the tiled disks get distorted as they get closer to or further from the origin.
This happens because the points are equally spaced along the spokes going out from the origin, but get further apart along the circles the further from the origin they are. Log-polar coordinates address this by changing the spacing of the points. The tiled disks get bigger and smaller, but remain circles.
These two tilings were made in JWildfire in much the same way as the rectangular tiling, but using the pTransform (for Polar Transformation) variation instead of linear. It has a parameter use_log that switches between polar and log-polar coordinates (1 for log-polar, 0 for polar). Two other parameters, rotate and move, specify how far to move the input along the circles or spokes respectively. Both of these tilings use four transforms with pTransform. Two have rotate set to 0 and move set to 0.5 or -0.5, which replicate the disk towards and away from the center, adjusting the size accordingly. The other two have move set to 0 and rotate set to 0.5236≈π/6 or -0.5236 (equivalent to ±30°), which move the disk in a circle around the origin.
Polar tilings can be used much like rectangular tilings, except that filling in the spaces exactly requires a trapezoidal shape, and there is no straightforward way to make one. So there will be either overlap or spaces. Change the variation on the first transform from blur to something more interesting, add a final transform or two, etc. Here we changed blur to lace_js and added a murl final.
The polar variation takes the polar coordinates (ρ,θ) of a point and treats them as rectangular coordinates, setting x=θ/π and y=ρ-1. Since θ will be between -π and π, x=θ/π will be between -1 and 1, and since ρ will be positive, y=ρ-1 will be between -1 and infinity. This puts most of the result in the sweet spot bounded left/right and top/bottom by -1/1. To see what this does, let’s take the polar tiling shown above and add a final polar. It becomes a distorted and truncated rectangular tiling.
Most of the distortion comes from scaling x by π; if we go to the post-affine transform for the final polar and change X1 to 3.14159 to approximate π, the ovals become more circular (though there is still some distortion). It is still truncated, but the right and left sides are out of the frame. We can move the flame up a bit so the flat top coincides with the top of the frame. This is a useful trick when using polar in a final transform, although any value can be used for X1 to make a pleasing result. It is usually not needed when using polar in a normal transform.
Polar can make interesting designs when paired with many other variations. As a base, create a new flame, add a transform, and change the variation to polar. Then add a second transform, change the amount for linear3D from 1 to 0.5, rotate the pre-affine triangle 180°, and set the color to 1.
The linear component is easy to see here in the rectangle at the bottom center containing a half-size upside-down copy of the whole flame. Its iterations can be seen as smaller and smaller copies going towards the center. The rest of the flame comes from iterations of polar, which bends and distorts the input. Exact correlations are hard to explain, but as one example, the line at the very bottom of the linear component maps to the arch at the bottom center of the polar component (above the linear part). Fortunately, we don’t need to understand the exact mappings to use polar effectively.
Some people will love the designs and negative space shapes this creates. Others will dislike the holes and overlaps. Both opinions are equally valid! It’s a matter of taste. It can be tweaked in the usual ways. Here, the linear3D has been changed to tan.
For the following images, the polar transform is moved down slightly. The first uses linear3D in the second transform. The second uses murl.
Since the result of polar has a fixed width, it can be paired effectively with splits, but we need to get polar to extend vertically up as well as down. We do that by adding post_mirror_wf to the polar transform, setting xaxis to 0 and yaxis to 1 so it reflects vertically. Here is a base splits-polar flame (parameters are in the flame pack linked below).
Here, the polar transform is rotated and a final auger added.
The polar2 variation is like polar, but it uses log-polar coordinates instead of polar coordinates. As with polar, x=θ/π, but unlike polar, y=ρ/2π. Just as we added a final transform with polar to a polar tiling, we now add a final transform with polar2 to a log-polar tiling and get a rectangular tiling that is truncated on the left and right sides since θ will always be between -π and π.
Polar2 also makes interesting designs when paired with other variations in the same way as polar, but the results are quite different. The following images use polar2 with linear3D, splits, and tan.
Polar2 also works well with splits; it already extends vertically in both directions, so post_mirror is not needed. Again, it has a very different character from polar. Here is a base splits-polar2 flame (parameters are in the flame pack linked below).
Here is a tweak, adding another transform with sigmoid among other changes.
|variation amount||Scale factor for the output.|
Brad Stefanov tutorial.