Assuming the initial 3 circles are in the coherent ratio, for maintaining radius ratios, i.e. to maintain external tangency, without circle overlap, the third circle selected would be the circle tangent in the opposite cleft.
Selecting a different 3rd circle, of different radius from the opposite circle, may be done at the whim of the user, but the resulting new circle will not maintain the coherency.
Spirals start with the circle centered at (1,0). To make a spiral with this script, to add one circle to the spiral, it is necessary to make two new circles, (usually), in order to have the helper circle for the next spiral circle. If p = q is used to set up coherence, with a 3rd party solver, the "spirals" are actually rings of circles, kind of like a spiral without curvature.
- Brian
After creating the new circle, right click will re-activate the Doyle flower script. (Pilou mentioned this "recall the function".)
Also after creating the new circle, it might be nice to have a deselectAll added to the Doyle flower script, but it is not essential.
A new script would automatically create the whole Doyle spiral, given user input parameters, with a few lines of code. Yet to be written or adapted from the abstruse mathematica code, to javascript. I'll work some more on a new script, after the bookkeeping gets done:-)
(Powers of the A (or B) circle centerpoint, as complex numbers, create spirals of center points of circles.)
Notepad++ prefers centre to center:-)
- Brian
It is amazing to me that a few simple circles have let to the many abstruse mathematical papers on the subject.
Complex number "w" = "C" = a + b*i, where a and b are real numbers.
Here, i = the square root of -1. So b*i is an imaginary number. Math.pow(i,2) = -1.
There are specific mathematical rules for complex number arithmetic.
Addition and Subtraction.
Multiplication.
Reciprocal for negative exponents.
Conjugation.
Rotation.
The complex numbers have similarities to vectors, and some differences...
A complex number may be represented in several ways, in nodeeditor and MoI.
For display purposes:
The complex number "w" may be treated as a point "C" in the MoI TopView, with the TopView plane considered to be an Argand plane.
The x_coordinate represents the real component, and the y_coordinate represents the imaginary component without showing i = sqrt(-1).
(The z value of C is absent or ignored.) In this case, C is a point object, a one member objectlist, gold color pip in nodeeditor.
For calculation purposes:
A complex number point ptC may be represented as an Element in a nodeeditor pointarray, a pink color pip in nodeeditor.
PointarrayC = [ptC, ptC1, ...]. The pointarray may have one or more points. Let the zero-ith point be ptC.
ptC = PointarrayC.getElement(0);
ptC = (x, y) = (ptC.data[0], ptC.data[1];
For math purposes, x and y elements may be extracted with the Extract node, or Javascript code from the Extract node.
For calculation purposes, the rules of complex number math must be followed.
For easier calculation purposes, a "duo_numarray", a numarray with only two entries, the x and y values, may be extracted from one point in a pointarray.
For more calculation purposes:
A complex number may also be represented in polar coordinates, as modulus (origin distance = hypotenuse(x,y)) and argument (angle in radians).
Pointarray C = [ mod_C * cos(arg_C), mod_C * sin(arg_C) ]
The modulus of C may be calculated from coordinates (x,y). mod_C = math.sqrt(x*x + y*y).
For Doyle spirals, the circles or spheres are calculated from master complex numbers "A" and "B", and masterRadius = "r".
The complex number centerpoints of circles = Math.pow( A, j ) * Math.pow( B, k ), for ranges of j's and k's.
The radius of a circle "D" = modulus_D * masterRadius.
mod_A and arg_A must be solved for, for given integers "p" and "q". The rest of the complex number centerpoints and radii are obtained by calculation.
It all sounds easy, but has been confusing. And confusing to implement. A node is getting close:-)
I am very happy that my DoyleCell node script is partly working.
It is producing the roots and circle centerpoints and master radius, but with 17 digits.
There may be a problem in nodeeditor with having 17 digits, or decimal digits. (FALSE, NOT A PROBLEM)
Circle node is not working with a radius of 17 decimal digits.
r = 0.43384321812883486
I am trying to apply javascript round to get 14 digits, code from the internet, which so far is not working.
There are some sort of javascript limits on numbers...
Attached is non-functional DoyleCell node.
doylefn.js is a helper function which solves for the two root, which are a modulus and an angle argument,
and is a slightly modified program of Robin Houston. It mimics perlinnoisefn.js.
doylefn.js is supplying the required master numbers.
doylecell.js is the node program.
Place both .js programs in the nodeeditor extension folder.
A little more work is needed...
- Brian
Edit, see functional DoyleCellBasic.zip, 4 posts down.
Okay, the confusion between Javascript arrays, numarrays, pointarrays, and passed root values is sorted out:-)
There is no problem with the number of decimal places. The previous numarrays and pointarrays were programmed incorrectly.
- Brian
Edit: Attached is a functional DoyleCell node. With helper nodes, the 3 basic circles of the spiral are drawn.
Place doylecell.js and doylefn.js in the nodeeditor extension directory. doylefn.js is not "linked" or "included", but its function is somehow found by nodeeditor.
Next up:
Complex number power math with ptA and ptB, to draw a spiral. Inward and outward circles.
Color/Style gradients.
Double Doyle spiral with two attractors, with moebius transform. (easy...really).
Log curves.
A double slider for p and q. Previous (brief) efforts resulted in failure of mouse to grab one slider.
Spheres will work instead of circles.
Edit multi-page Doyle Spiral pdf again, with derivation of Jos Leys equations.
Might try to get my 27 ratio equations, 18 of which are partial derivatives, to work. (not needed, but there is no license for Robin Houston code AFAIK,
just a message to have fun...)
New nodes could be created, or Macros may be able to do the work...
Might need some complex number math nodes.
A preliminary Complex number node menu, work in progress.
Contains MultiComplex, short for multiply two complex numbers, which are each in the form of a two-element numarray.
I think it may be easier, in using nodes and macros, to deal with a complex number as a 2-element numarray, rather than a two element pointarray.
Later convert the two-element numarray into a point, which may take a macro or another node...
Using more "ported" code, the Doyle spiral of circles is being formed, but only one arm.
I think that the arms are being calculated, but only the last arm survives.
Saving by .concat of pointarray and .concat of radii numarray, or .push do not seem to work...maybe xlength needs to be set?
So it is back to debugging:-)
- Brian
The problem was that I had an old version, renamed DoyleSpiralOneArm.js in the extension folder, which functioned partly, and one misnamed variable in the DoyleSpirals.js file, r instead of rMaster. (The old version loaded in the menu as DoyleSpiral.)
(apparently) nodeeditor scans ALL of the .js files in the extensions folder,
so somehow the functions in the old version were interfering with the latest version.
Or, more likely, the old version was running instead of the newer version?
Every time I edited DoyleSpirals.js and copied it to the extensions folder, nothing changed or improved. A few hours of wasted time, but educational.
I finally changed the values of p and q from 3 & 8 to 4 and 6, which revealed that the old version was running.
So a suggestion woule be to get rid of old versions in the extensions folder,
and make a visual modification to the newest version.
Here is a beta copy of the DoyleSpiral script, which gives basic spirals.
It is a "port" of Robin Houston DoyleSpiral explorer code. The buildArm function code was moved inline, during debugging, and could be separated out.
This script was build by using and modifying the pattern of the previous DoyleCell script, so the Root Solver is still doylefn.js.
There is more work to do.
Adding color styles or gradients, varying by arm would be nice.
Only q_arms are implemented. p_arms are not implemented, which would require exchanging the roles of points a and b.
Right hand spirals would need complex conjugate added, or do it in MoI later.
Moebius transform may be possible by math nodes(?).
Due to increasing seasonal work load, improvements may be slow...
modMin and modMax are essentially modulus boundary circles centered at the origin, and all of the circle centers of the Doyle circles, (or spheres),
occur between these boundaries.
For some large values of p and q, there are circles formed for some quadrants which exceed the modulus boundary of modMax,
for unknown reason.
There is a demo .nod file, which can be loaded to the nodeeditor canvas
"Correct" values for p and q are 1 <=p <=q, with 2<q, but some "incorrect" values for p and q form other circle patterns...
Some other "incorrect" values Alert that a root cannot be calculated.
Place DoyleSpiral.js and doylefn.js in the nodeeditor extensions folder.
It is OK to leave the DoyleCell.js file there, but remove any other old DoyleSpiral.js files.
Place the rudimentary DoyleSpiral.html file in extensions/Documents/EN folder.
With up to date nodeeditor program, the .html file will be view-able under the
nodes right-click info button.
A French version translation could be placed in the FR folder.
Here is a DoubleDoyleDemo2 spiral, made from nodes, with two attractor points, x = -1 and x = +1.
(Code from Robin Houston was used.)
x=-1 is the regular Doyle attractor, moved from 0 to -1.
x=+1 attractor point represents infinity.
The 4 Macros used were:
1. ConvertCenters.nod (creates 3 points on each existing Doyle circle.)
2. MoebiusTr_0_1_inf_to_neg1_0_1.nod (Moebius transform maps x=0 to x=-1,
maps x=1 to x=0, and maps x=infinity to x=+1. This formula is then applied to all of the 3_point circle points. The mapped sets of 3 points are then run through the MoI's 3_point circle node. One extra step is to get the center Y value of each mapped circle, and mask out those circle which have absolute value greater than 5.5. (The value is supposed to be 10, but the math seems to be working wrong...) This gets rid of huge circles, and two very large circles which appear to be incorrect, for unknown reason.
(Mapped circles are produced, because (extended) circles are mapped to (extended) circles, by the moebius transform.) Note Pilou's video post. The moebius transform represents reverse stereographic projection to a sphere, rotation of the sphere by 90 degrees with a certain axis, and then stereographic projection back to the MoI Top View.
It is sufficient to only map 3 points per original circle.
3. Extract_XY node. This converts a pointarray point into a Duo-numarray, representing a complex number.
4. Extract_2XY nod macro. Same as #3, with two point inputs, and outputs X1 Y1 X2 Y2,
Place the 4 Macros in the Macros folder.
Run the DoubleDoyleDemo2.nod.
(Assumes that DoyleSpiral.js and doylefn.js are already in the extension folder of nodeeditor.)
One other point. The math.hypot may be better and less error prone that the current formula for hypotenuse. (Not tried yet.)
Thing would look much better with colors and planar...
The maxModulus and minModulus were adjusted so that the neighborhood of the two attractor points looked about the same.
Modifying to more extreme values may hang up the computer, but on windows 10, MoI can be closed in Task Manager.
Thank you for the nice style by circle size version.
When time permits, I'll add some style to the Doyle Spiral node, by arm, or position in arm.
Or gradients.
Adding an indexByArm output, and an indexByPositionInArm output might suffice?
There are two arm possibilities, "rows" or "columns" corresponding to p and q.
Maybe even rotation animation.
MoI scaling would move the two attractors apart.
Note that circle C of the Doyle cell is mapped and relocated from center (1,0) to center (0,0), with mapped A and mapped B circles still tangent.
For a different moebius transformation separation of the attractors, the formulas would have to be recalculated. I think this would be a scaling as well(?).
- Brian
I'll have to try sphere replacement. Cannot remember if such a script was written yet.
p.s. It seems that one circle near -1 does not get colored?
The create rainbow function may have a "bug" which causes the White/Black 4th circle in to not have "blue" shade of style(???)
I modified the for loop to i <= 255, instead of i<255, and now the 4th circle has a "blue" style, BUT it is too intense.
Maybe the sigmoid equations need to slightly modified???
Due to my ignorance of the sigmoid equations, whether or not this is a bug is unclear.
Karsten's (?) create rainbow function is located in nodeeditor extension/libs folder, inside basicfunctions.js.
The function is called by setStyle node.
For the color adding nodes, Switching the constant 255,0 to 0,255 results in the irregular 4th circle to be orange, but too dark a shade, and the two large circles on the far right to be white/black. Adding the <= to the rainbow for loop colors the two large circles to blue shade.
So I conclude that there are two problems.
1. add the <= to fix blue colors.
2. something is wrong with the way the 4th circle is measured and/or turned into a style index. Maybe related to number of digits??
I wonder if the new circumference availability for MoI 4 could be used for indexing?
May try some of the recent Gradients code.
Deriving the moebius transformation that maps 3 points to 3 other points
is explained here(section 3.4.11 Building a mobius transformation): https://mphitchman.com/geometry/section3-4.html
Using equated cross ratios. (handling infinity is also explained.)
After about 8 pages of tedius hand calculation with many corrected mistakes,
the moebius transformation and the x and y formulas were calculated, for the current mapping of the attractor points to -1 and +1, and also to
-2 and +2 . The simple expected result is that this scaling by 2 is equivalent to multiplying the x and y formulas by 2. So a scaling input could be added to the double doyle. Or the scaling could be done after forming the double doyle, by MoI scaling.
The original moebius transformation is V(z) = (z-1)/(z+1).
The 2 times scale moebius transformation is V(z) = 2*(z-1)(z+1).
For the x and y formulas:
The new denominator is the same as used in double doyle node.
denom = (x+1)*(x+1) + y*y.
The numerator is 2 times the original numerator.
New numer = 2*((x*x - 1) + (y*y))