mclarekin
|
|
« Reply #30 on: October 28, 2015, 12:39:44 PM » |
|
Because I wanted to be able to reproduce images I had made in Mandelbulber OpenCL versions. I like to explore with the constants being variable. And if I ever did morph animation I would need it that way. Attached images I think are all just the BenesiMagTranformOne with the variables adjusted. No pineTree.
|
|
|
Logged
|
|
|
|
M Benesi
|
|
« Reply #31 on: October 28, 2015, 04:51:47 PM » |
|
Looks good. I stuck with single offsets and scales, instead of vectors, because I thought they introduced too much variety, but actually... sort of cool. Nice work! Try doing a y-z switch after T1, and see what you get for the same values above... might be interesting. This is C++ versions, ( WARNING McLarekin code may contain mistakes, bad coding and un-optimisations.) It is easy to read. I like that. To make T2,T3,T4,T5b, change the central part (first one below is T4). CVector3 temp = z; CVector3 tempV1; CVector3 newZ; tempV1.x = z.x * 0.81649658092772603273242802490196 - z.z * 0.57735026918962576450914878050196; newZ.z = z.x * 0.57735026918962576450914878050196 + z.z * 0.81649658092772603273242802490196; newZ.x = (tempV1.x - z.y) * 0.70710678118654752440084436210485; newZ.y = (tempV1.x + z.y) * 0.70710678118654752440084436210485;
// Change this for different transforms This is T4: newZ.x = fabs(newZ.z * newZ.z + newZ.y * newZ.y - benesiMagTransform4.offset.x) * benesiMagTransform4.scale.x ; newZ.y = fabs(newZ.z * newZ.z + newZ.x * newZ.x - benesiMagTransform4.offset.y) * benesiMagTransform4.scale.y ; newZ.z = fabs(newZ.x * newZ.x + newZ.y * newZ.y - benesiMagTransform4.offset.z) * benesiMagTransform4.scale.z ;
tempV1.x = (newZ.x + newZ.y) * 0.70710678118654752440084436210485; newZ.y = (-newZ.x + newZ.y) * 0.70710678118654752440084436210485; newZ.x = tempV1.x * 0.81649658092772603273242802490196 + newZ.z * 0.57735026918962576450914878050196; newZ.z = -tempV1.x * 0.57735026918962576450914878050196 + newZ.z * 0.81649658092772603273242802490196; z = newZ ; // applying six variables:- scale.x, scale.y, scale.z, offset.x, offset.y, offset.z
So put these in the middle section for T3 and T5b. //For T3: newZ.x = fabs(fabs(newZ.z) + fabs(newZ.y) - benesiMagTransform3.offset.x) * benesiMagTransform3.scale.x ; newZ.y = fabs(fabs(newZ.z) + fabs(newZ.x) - benesiMagTransform3.offset.y) * benesiMagTransform3.scale.y ; newZ.z = fabs(fabs(newZ.x) + fabs(newZ.y) - benesiMagTransform3.offset.z) * benesiMagTransform3.scale.z ;
// I don't know how optimized the compiler you're using is?? if x^8 = x^2; x^2; x^2;... it's good. I also don't know // if you can do 4th roots, so I did 2 square root operations in a row. Don't know the name of the square root command // so I used sqrt(x), although it might be fsqrt(x) or gorgleflummuxmopmop(x), for all I know... // for T5b:
// I wrote the pow function into this... if you want to try it.. original is below. // with pow: newZ.x = fabs(sqrt(sqrt(pow(newZ.z,8) + pow(newZ.y,8))) - benesiMagTransform5.offset.x) * benesiMagTransform5.scale.x; newZ.y = fabs(sqrt(sqrt(pow(newZ.z,8) + pow(newZ.x,8))) - benesiMagTransform5.offset.y) * benesiMagTransform5.scale.y; newZ.z = fabs(sqrt(sqrt(pow(newZ.x,8) + pow(newZ.y,8))) - benesiMagTransform5.offset.z) * benesiMagTransform5.scale.z;
// no pow:
newZ.x = fabs(sqrt(sqrt(newZ.z^8 + newZ.y^8)) - benesiMagTransform5.offset.x) * benesiMagTransform5.scale.x; newZ.y = fabs(sqrt(sqrt(newZ.z^8 + newZ.x^8)) - benesiMagTransform5.offset.y) * benesiMagTransform5.scale.y; newZ.z = fabs(sqrt(sqrt(newZ.x^8 + newZ.y^8)) - benesiMagTransform5.offset.z) * benesiMagTransform5.scale.z;
|
|
« Last Edit: October 29, 2015, 06:17:54 AM by M Benesi »
|
Logged
|
|
|
|
mclarekin
|
|
« Reply #32 on: October 28, 2015, 09:30:42 PM » |
|
I was wondering why there were no vectors Now you know why my progress on T2, T3 etc has been slow. It is because T1 is soooooooooooooo much fun. So placing a T1 as first or second position in a loop has a dramatic influence on any fractal, and it can be easily controlled with the six variables. The Benesi_Transforms UI already had the transforms to build a Mbox so I tested it last night, cool. I have yet to cut & paste a menger into the UI but I suspect that it will keep me interested for a while. So with my code, with Pt XYZ I simply zero cx and cy then I have PTnoYZ . T1 will eventually be divided into three transforms. so that I can drop "anything" into the middle to experience the mag folds
|
|
|
Logged
|
|
|
|
M Benesi
|
|
« Reply #33 on: October 28, 2015, 11:53:02 PM » |
|
The problem with separating the rotations from the transforms, at least for M3D, is that it takes up 3 formula slots to do a single transform.
So I like to have them combined. It's even better, for some cases, to have them combined with the Pine Tree Mandelbulb formula (like Luca did with transform 1), without the y and z pixel components (although I could just build multipliers into the formula, like you did).
So, for M3D, the project is to get the pixel multiplier components added in. Also, maybe add different scale and offset for each variable, although that is a bit more work for assembly than it is for C or Delphi... and I've already ran into some problems with creating assembly formulas that should have worked fine, but ended up doing weird stuff.
|
|
|
Logged
|
|
|
|
mclarekin
|
|
« Reply #34 on: October 29, 2015, 03:00:55 AM » |
|
Thank you for the coding, it is the converting where I make my most mistakes. Now if you would only put a space, before and after, your + = - *, I would just have to cut & paste. Another great thing about these magTransforms is they uses the same controls (scale & offset). so I can use the same groupbox template for each one. so I used sqrt(x), although it might be fsqrt(x) or gorgleflummuxmopmop(x), it is the last one.LOL Wait a minute I will have to check, yep, sqrt(x). and I guess its exp( x, n ) for powers. I could be wrong. Until I added the “start @ iter/ stop @ iter “controls, I had been avoiding more expensive functions in the transforms. Your Pinetrees are great examples to demonstrate how a single transform iteration placed early in the loop, makes a huge change to the fractal. So running an expensive transform once, instead of 10 - 40 iterations, makes a big saving.. As I don't do maths well any more, can you tell me this:- I render a BenesiMagTranformOne then change the global view of the fractal to get it aligned with x,y,z axis by applying rotations of 90 degrees to x_axis and about 35 degrees to the y_axis. Do you know what this angle actually is or how it is derived? Cheers
|
|
|
Logged
|
|
|
|
M Benesi
|
|
« Reply #35 on: October 29, 2015, 06:13:10 AM » |
|
Thank you for the coding, it is the converting where I make my most mistakes. Now if you would only put a space, before and after, your + = - *, I would just have to cut & paste. Didn't know about the space. You got it. Actually.. I'll go back and check, did the +,-, and *.... not the equals. Seriously? What language requires this for special characters? Or are you teasing me (which would be totally fine, just curious)? it is the last one.LOL Yeah. I've never been able to figure out why they use sqrt(x) instead of gorgleflummuxmopmop(x) in some of these new compilers. It makes no sense. Anyway, we'll just have to deal with the weird terminology, such as sqrt(x), when dealing with square roots, because of the way the compilers are written. and I guess its exp( x, n ) for powers. I could be wrong. Until I added the “start @ iter/ stop @ iter “controls, I had been avoiding more expensive functions in the transforms. Ok, so you'll have to try out different things. If it's C++ (I saw a lot of .cpp files in the source)... pow!!!! pow(x,n); http://www.cplusplus.com/reference/cmath/pow/ If it's Delphi (I recently read that something was written in Delphi- it might be M3D???), then it depends on what libraries are included... There is a big Delphi reference library here.I render a BenesiMagTranformOne then change the global view of the fractal to get it aligned with x,y,z axis by applying rotations of 90 degrees to x_axis and about 35 degrees to the y_axis. Do you know what this angle actually is or how it is derived? I know what the angle is called (and it can be found in many things- I found it in a fractal I was playing with years ago). I was trying to face the fractal square on, and I moved around until I was zoomed exactly at a certain point. Then sometime later I found out what the angle was.... It's: https://en.wikipedia.org/wiki/Magic_angle (the Wikipedia article on tetrahedral molecular geometry is also interesting, if you feel like reading a bit further) Technically, we use 90 - the magic angle (pi/2 - acos(1/sqrt(3)) for our first rotation, and 45, aka pi/4, for our second. I tried the other rotation method of using a single rotation (just using the magic angle), around a vector from (0,-1, 1) to (0,1,-1), and I can't recall specifically why I picked this one. I think I liked the 2 rotation method more.. or maybe it was easier to implement. To tell you the truth, I think the single rotation method looked slightly different, so I had to rotate around the x axis first anyway to achieve the same effect??? It was over a year ago.. maybe I didn't implement the single rotation method correctly. I can't remember. The transforms, by themselves, don't change with the rotations. The rotations are to align the Mandelbulb and the transforms so that they work well together.... :shrug:
|
|
« Last Edit: October 29, 2015, 06:32:00 AM by M Benesi »
|
Logged
|
|
|
|
mclarekin
|
|
« Reply #36 on: October 29, 2015, 07:36:03 AM » |
|
the spaces are for readability, with my poor eyesight on my laptop screen. ooops, pow(x,n) seems much better LOL. You have been warned, I am a magnet for mistakes. Apparently www.cplusplus.com is good for those who can understand that stuff. The "magic_number" . H'mmmmm , I cannot get T2 to work, can you see anything wrong? //benesiMagTransformTwo 3D void benesiMagTransformTwoTransform3D(const sTransformBenesiMagTransformTwo &benesiMagTransformTwo, CVector3 &z, int i) { if (benesiMagTransformTwo.control.enabled && i >= benesiMagTransformTwo.control.startIterations && i < benesiMagTransformTwo.control.stopIterations) { CVector3 temp = z; // STEP1: "Benesi fold 2" double tx = (z.x * 0.81649658092772603273242802490196 - z.z * 0.57735026918962576450914878050196) * 0.70710678118654752440084436210485; z.y = z.y * 0.70710678118654752440084436210485; z.z = (z.x *0.57735026918962576450914878050196 + z.z * 0.81649658092772603273242802490196) * (z.x * 0.57735026918962576450914878050196 + z.z * 0.81649658092772603273242802490196); tx = (tx - z.y) * (tx - z.y); double ty = (tx + z.y) * (tx + z.y);
z.x = fabs(sqrt(ty + z.z) - benesiMagTransformTwo.offset.x) * benesiMagTransformTwo.scale.x; z.y = fabs(sqrt(tx + z.z) - benesiMagTransformTwo.offset.y) * benesiMagTransformTwo.scale.y ; z.z = fabs(sqrt(tx + ty) - benesiMagTransformTwo.offset.z) * benesiMagTransformTwo.scale.z ;
tx = z.y + z.x; z.y = z.y - z.x; z.x = z.z * 0.57735026918962576450914878050196 + tx * 0.81649658092772603273242802490196; z.z = z.z * 0.81649658092772603273242802490196 - tx * 0.57735026918962576450914878050196;
|
|
|
Logged
|
|
|
|
mclarekin
|
|
« Reply #37 on: October 29, 2015, 11:37:57 PM » |
|
So T2 didnt work T4 didnt work, so I had an excuse to stop and have fun instead.
So we drop T1 into a Menger_ Sponge_ UI with fast LinearDE. Hmmmm seems a bit tricky with the DE, just have to find what works.
Working with the Menger I begin to see that T1 is a fast non-trig rotation to the mag axis and back with something happening in between, with an amazing amount of shapes formed from the variables parameter controls. MEGA COOL. (Correct me if I am wrong).
Some of the possibilities T1 & Menger
|
|
|
Logged
|
|
|
|
M Benesi
|
|
« Reply #38 on: October 30, 2015, 12:54:22 AM » |
|
Very cool with the T1. By itself, if you switch the variables afterwords... does some neat stuff. I like what you did with the Menger... Not sure why T2 and T4 don't work... I'll look at your implementation of T2 a bit later- still planting a whole bunch of ground cover, and snuck away to check out fractal stuff.
|
|
|
Logged
|
|
|
|
M Benesi
|
|
« Reply #39 on: October 30, 2015, 01:04:45 AM » |
|
the spaces are for readability, with my poor eyesight on my laptop screen. Ok.. I'll try to keep that in mind. Magic angle spin, it's what we do to make the Mandelbulb work, just like they do it in solid state Nuclear Magnetic Resonance.... H'mmmmm , I cannot get T2 to work, can you see anything wrong? Yes.... yes I can. :p You forgot to multiply by square root of .5 (at the bottom).... I fixed it. I might have missed something else. I better get back to gardening before the sun goes down. Thanks for the fun! I'm pretty sure I coded T4 for you up above... ?? I'll be back. //benesiMagTransformTwo 3D void benesiMagTransformTwoTransform3D(const sTransformBenesiMagTransformTwo &benesiMagTransformTwo, CVector3 &z, int i) { if (benesiMagTransformTwo.control.enabled && i >= benesiMagTransformTwo.control.startIterations && i < benesiMagTransformTwo.control.stopIterations) { CVector3 temp = z; // STEP1: "Benesi fold 2" double tx = (z.x * 0.81649658092772603273242802490196 - z.z * 0.57735026918962576450914878050196) * 0.70710678118654752440084436210485; z.y = z.y * 0.70710678118654752440084436210485; z.z = (z.x *0.57735026918962576450914878050196 + z.z * 0.81649658092772603273242802490196) * (z.x * 0.57735026918962576450914878050196 + z.z * 0.81649658092772603273242802490196); tx = (tx - z.y) * (tx - z.y); double ty = (tx + z.y) * (tx + z.y);
z.x = fabs(sqrt(ty + z.z) - benesiMagTransformTwo.offset.x) * benesiMagTransformTwo.scale.x; z.y = fabs(sqrt(tx + z.z) - benesiMagTransformTwo.offset.y) * benesiMagTransformTwo.scale.y ; z.z = fabs(sqrt(tx + ty) - benesiMagTransformTwo.offset.z) * benesiMagTransformTwo.scale.z ;
// you forgot the square root of .5.... tx = (z.y + z.x) * 0.70710678118654752440084436210485; //was tx = z.y + z.x; z.y = (z.y - z.x) * 0.70710678118654752440084436210485; //was z.y = z.y - z.x; z.x = z.z * 0.57735026918962576450914878050196 + tx * 0.81649658092772603273242802490196; z.z = z.z * 0.81649658092772603273242802490196 - tx * 0.57735026918962576450914878050196;
|
|
|
Logged
|
|
|
|
mclarekin
|
|
« Reply #40 on: October 30, 2015, 04:30:55 AM » |
|
T4 is based on T1 with the applications of constants moved. So it should work. but I just get some parallel cylinders instead of the Apollonian gasket looking thing that you had for T2 & T4. T2, I rewrote, it now has tempV1 and newZ, so looks similar to the others. To me the problem should be in the first few lines, it is quite different to T1 & T4. { CVector3 temp = z; CVector3 tempV1; CVector3 newZ; // STEP1: "Benesi fold 2" tempV1.x = (newZ.x * 0.81649658092772603273242802490196 - newZ.z * 0.57735026918962576450914878050196) * 0.70710678118654752440084436210485; newZ.y = newZ.y * 0.70710678118654752440084436210485; newZ.z = (newZ.x * 0.57735026918962576450914878050196 + newZ.z * 0.81649658092772603273242802490196) * (newZ.x * 0.57735026918962576450914878050196 + newZ.z * 0.81649658092772603273242802490196);
tempV1.x = (tempV1.x - newZ.y) * (tempV1.x - newZ.y); tempV1.y = (tempV1.x + newZ.y) * (tempV1.x + newZ.y);
newZ.x = fabs(sqrt(tempV1.y + newZ.z)); // missing some brackets newZ.y = fabs(sqrt(tempV1.x + newZ.z)); newZ.z = fabs(sqrt(tempV1.x + tempV1.y));
newZ = (newZ - benesiMagTransformTwo.offset) * benesiMagTransformTwo.scale;
tempV1.x = (newZ.y + newZ.x) * 0.70710678118654752440084436210485; newZ.y = (newZ.y - newZ.x) * 0.70710678118654752440084436210485; newZ.x = newZ.z * 0.57735026918962576450914878050196 + tempV1.x * 0.81649658092772603273242802490196; newZ.z = newZ.z * 0.81649658092772603273242802490196 - tempV1.x * 0.57735026918962576450914878050196;
|
|
« Last Edit: October 30, 2015, 05:03:10 AM by mclarekin, Reason: missing some brackets »
|
Logged
|
|
|
|
mclarekin
|
|
« Reply #41 on: October 30, 2015, 05:07:38 AM » |
|
ooops missing some brackets in previous post. Now the magTransform box has 9 spots on each face. //newZ.x = fabs(newZ.x); //newZ.y = fabs(newZ.y); //newZ.z = fabs(newZ.z); newZ.x = fabs( newZ.x + benesiMagTransformOne.offset.x) - fabs( newZ.x - benesiMagTransformOne.offset.x ) - newZ.x ; newZ.y = fabs( newZ.y + benesiMagTransformOne.offset.y) - fabs( newZ.y - benesiMagTransformOne.offset.y ) - newZ.y ; newZ.z = fabs( newZ.z + benesiMagTransformOne.offset.z) - fabs( newZ.z - benesiMagTransformOne.offset.z ) - newZ.z ; //newZ = fabs( newZ + benesiMagTransformOne.offset) - fabs( newZ - benesiMagTransformOne.offset ) - newZ ;
tempV1.x = (newZ.y + newZ.x) * 0.70710678118654752440084436210485; newZ.y = (newZ.y - newZ.x) * 0.70710678118654752440084436210485; newZ.x = newZ.z * 0.57735026918962576450914878050196 + tempV1.x * 0.81649658092772603273242802490196; newZ.z = newZ.z * 0.81649658092772603273242802490196 - tempV1.x * 0.57735026918962576450914878050196 ; z = benesiMagTransformOne.scale * newZ; //- benesiMagTransformOne.offset;
|
|
|
Logged
|
|
|
|
mclarekin
|
|
« Reply #42 on: October 30, 2015, 05:40:17 AM » |
|
and if you want a lot of control over fabs() albeit slower , you insert this instaed // fabsFormulaABCD z = fabs( z + const.A ) - fabs( z - const.B ) + ( z * const.C + const.D ); 3D void fabsFormulaABCDTransform3D(const sTransformFabsFormulaABCD &fabsFormulaABCD, CVector3 &z, int i) { if (fabsFormulaABCD.control.enabled && i >= fabsFormulaABCD.control.startIterations && i < fabsFormulaABCD.control.stopIterations) { CVector3 temp = z; CVector3 tempA = z * 0; CVector3 tempB = z * 0; if (fabsFormulaABCD.fabsFormulaABCDEnabledAx) { tempA.x = fabs(z.x + fabsFormulaABCD.fabsFormulaABCDA.x); } if (fabsFormulaABCD.fabsFormulaABCDEnabledBx) { tempB.x = fabs(z.x - fabsFormulaABCD.fabsFormulaABCDB.x); } z.x = tempA.x - tempB.x + (z.x * fabsFormulaABCD.fabsFormulaABCDC.x + fabsFormulaABCD.fabsFormulaABCDD.x); if (fabsFormulaABCD.fabsFormulaABCDEnabledAy) { tempA.y = fabs(z.y + fabsFormulaABCD.fabsFormulaABCDA.y); } if (fabsFormulaABCD.fabsFormulaABCDEnabledBy) { tempB.y = fabs(z.y - fabsFormulaABCD.fabsFormulaABCDB.y); } z.y = tempA.y - tempB.y + (z.y * fabsFormulaABCD.fabsFormulaABCDC.y + fabsFormulaABCD.fabsFormulaABCDD.y); if (fabsFormulaABCD.fabsFormulaABCDEnabledAz) { tempA.z = fabs(z.z + fabsFormulaABCD.fabsFormulaABCDA.z); } if (fabsFormulaABCD.fabsFormulaABCDEnabledBz) { tempB.z = fabs(z.z - fabsFormulaABCD.fabsFormulaABCDB.z); } z.z = tempA.z - tempB.z + (z.z * fabsFormulaABCD.fabsFormulaABCDC.z + fabsFormulaABCD.fabsFormulaABCDD.z);
|
|
|
Logged
|
|
|
|
M Benesi
|
|
« Reply #43 on: October 30, 2015, 06:30:49 AM » |
|
eeeek! Did some frags (Fragmentarium code clean ups) today.. brain is tired. Keep up the good work.
|
|
|
Logged
|
|
|
|
mclarekin
|
|
« Reply #44 on: November 01, 2015, 04:39:31 AM » |
|
Set up the Benesi_Transforms UI with a magFoward at the beginning with a magBack half way down and lots of transforms in between. Was interesting when I used the UI to recreate T1 out of five transforms, as there was not much increase in render time. Checked out your .frag, looks good, with a lot of parameters to tweak . I will update the Benesi_Transforms UI by moving scale functions to the middle. I have got 38 transforms in that UI now, including Menger, Mbulbs, & Mbox, ugh, I need to do some pruning. And I must see if I can get the DE calc working ( generally outside my ability.) Dropped the nine spot magTransform into T2s spot for now. Defaults: Scale = 3.0's and offset = 1.0s. It is not as much fun as T1. CVector3 temp = z; CVector3 tempV1; CVector3 newZ; tempV1.x = z.x * 0.81649658092772603273242802490196 - z.z * 0.57735026918962576450914878050196; newZ.z = z.x * 0.57735026918962576450914878050196 + z.z * 0.81649658092772603273242802490196; newZ.x = (tempV1.x - z.y) * 0.70710678118654752440084436210485; newZ.y = (tempV1.x + z.y) * 0.70710678118654752440084436210485;
newZ *= benesiMagTransformTwo.scale; newZ = (fabs( newZ + benesiMagTransformTwo.offset) - fabs( newZ - benesiMagTransformTwo.offset ) - newZ) ;
tempV1.x = (newZ.y + newZ.x) * 0.70710678118654752440084436210485; newZ.y = (newZ.y - newZ.x) * 0.70710678118654752440084436210485; newZ.x = newZ.z * 0.57735026918962576450914878050196 + tempV1.x * 0.81649658092772603273242802490196; newZ.z = newZ.z * 0.81649658092772603273242802490196 - tempV1.x * 0.57735026918962576450914878050196 ;
z = newZ;
|
|
|
Logged
|
|
|
|
|