public ComputedFractalValues ReturnComputedFractalValues(RectangleInPlane fractalRectangleIn, int xMaxIn, int yMaxIn, IList <FractalColorValue> fractalColorValuesIn, System.Windows.Forms.ProgressBar fractalProgressIn) { if (fractalColorValuesIn.Count < NumberOfColorUsed) { throw new FractalObserverException("Fractal PythagorasTree needs more colors that are available in the input parameter fractalColorValuesIn!"); } ComputedFractalValues aComputedFractalValuesValues = new ComputedFractalValues(); for (int aCurrentYPos = 0; aCurrentYPos < yMaxIn; aCurrentYPos++) { fractalProgressIn.Value = (int)(100.0 * ((double)aCurrentYPos / (double)yMaxIn)); for (int aCurrentXPos = 0; aCurrentXPos < xMaxIn; aCurrentXPos++) { int tempValue = 0; ComplexNumber c = new ComplexNumber(); c.Re = fractalRectangleIn.StartX + Math.Abs(fractalRectangleIn.StartX - fractalRectangleIn.EndX) * ((double)aCurrentXPos / (double)xMaxIn); c.Im = fractalRectangleIn.StartY + Math.Abs(fractalRectangleIn.StartY - fractalRectangleIn.EndY) * ((double)aCurrentYPos / (double)yMaxIn); int n = 0; myZValues[n].Re = 0.0; myZValues[n].Im = 0.0; // computation of value for function z2+c, if it converges (if it is bounded) the point is part of mandelbrot set do { n++; myZValues[n] = ComplexOperations.Add(Equation.ComplexFunctionValue(myZValues[n - 1]), c); } while (((Math.Abs(myZValues[n].Re) < myMaximumValueForConvergation) && (Math.Abs(myZValues[n].Im) < myMaximumValueForConvergation)) && (n < (MaximumNumberOfIterations - 1))); tempValue = n; ComputedFractalValue aCFValue = new ComputedFractalValue(); FractalColorValue aFractalColorValue = ReturnColor(tempValue, fractalColorValuesIn); aCFValue.ColorValue = aFractalColorValue; aCFValue.AddComputedPoint(new System.Drawing.Point(aCurrentXPos, aCurrentYPos)); aCFValue.TypeOfShape = TypesOfShape.Point; aCFValue.UsedTypeOfCoordinateSystem = TypesOfCoordinateSystem.Screen; aComputedFractalValuesValues.AddComputedFractalValue(aCFValue); } } return(aComputedFractalValuesValues); }
// recursive method - this method computes the points of snowflake private void CreateNewCurveAndAddItToCFV(PointInPlane startPointIn, PointInPlane endPointIn, IList <FractalColorValue> fractalColorValuesIn, ref ComputedFractalValue cfvIn, int currentIterationIn) { if (currentIterationIn < (MaximumNumberOfIterations - 1)) { const double aAngle = Math.PI / 3.0; // angle of 60 degrees - equilateral triangle PointInPlane aOneThirdPoint = new PointInPlane(startPointIn.x + (endPointIn.x - startPointIn.x) / 3.0, startPointIn.y + (endPointIn.y - startPointIn.y) / 3.0); PointInPlane aTwoThirdPoint = new PointInPlane(startPointIn.x + (endPointIn.x - startPointIn.x) / 1.5, startPointIn.y + (endPointIn.y - startPointIn.y) / 1.5); PointInPlane aRotatedLinePoint = RotateLine(aOneThirdPoint, aTwoThirdPoint, aAngle); CreateNewCurveAndAddItToCFV(startPointIn, aOneThirdPoint, fractalColorValuesIn, ref cfvIn, currentIterationIn + 1); CreateNewCurveAndAddItToCFV(aOneThirdPoint, aRotatedLinePoint, fractalColorValuesIn, ref cfvIn, currentIterationIn + 1); CreateNewCurveAndAddItToCFV(aRotatedLinePoint, aTwoThirdPoint, fractalColorValuesIn, ref cfvIn, currentIterationIn + 1); CreateNewCurveAndAddItToCFV(aTwoThirdPoint, endPointIn, fractalColorValuesIn, ref cfvIn, currentIterationIn + 1); } else { cfvIn.AddComputedPoint(startPointIn); cfvIn.AddComputedPoint(endPointIn); } }
// recursive method - here are computed the squares of pythagoras tree private void CreateSquare(PointInPlane[] rectanglePointsIn, IList <FractalColorValue> fractalColorValuesIn /*, SquareOrientation squareOrientationIn*/, ref ComputedFractalValues cfvIn, int currentIterationIn) { if (rectanglePointsIn.Length < 4) { throw new FractalObserverException("The input parameter rectanglePointsIn in Methode CreateSquare must have at least four values (for each vertex one) !"); } ComputedFractalValue aCFValue = new ComputedFractalValue(); FractalColorValue aFractalColorValue = ReturnColor(currentIterationIn, fractalColorValuesIn); aCFValue.ColorValue = aFractalColorValue; aCFValue.TypeOfShape = TypesOfShape.Rectangle; aCFValue.UsedTypeOfCoordinateSystem = TypesOfCoordinateSystem.Plane; aCFValue.AddComputedPoint(rectanglePointsIn[0]); aCFValue.AddComputedPoint(rectanglePointsIn[1]); aCFValue.AddComputedPoint(rectanglePointsIn[2]); aCFValue.AddComputedPoint(rectanglePointsIn[3]); cfvIn.AddComputedFractalValue(aCFValue); if (currentIterationIn < MaximumNumberOfIterations) { double aScalingCoefficient = 1.0 / Math.Sqrt(2.0); double aRotationAngle = Math.PI / 4.0; { // right rectangle values computed PointInPlane[] aNewRightRectangle = new PointInPlane[4]; PointInPlane aMovingVector = rectanglePointsIn[2] - rectanglePointsIn[1]; // scale to new rectangle aNewRightRectangle[1] = rectanglePointsIn[1]; aNewRightRectangle[0] = PointInPlane.ScalePoint(rectanglePointsIn[1], rectanglePointsIn[0], aScalingCoefficient); aNewRightRectangle[2] = PointInPlane.ScalePoint(rectanglePointsIn[1], rectanglePointsIn[2], aScalingCoefficient); aNewRightRectangle[3] = PointInPlane.ScalePoint(rectanglePointsIn[1], rectanglePointsIn[3], aScalingCoefficient); // rotate to new rectangle aNewRightRectangle[0] = PointInPlane.RotatePoint(aNewRightRectangle[0], aNewRightRectangle[1], aRotationAngle); aNewRightRectangle[1] = PointInPlane.RotatePoint(aNewRightRectangle[1], aNewRightRectangle[1], aRotationAngle); aNewRightRectangle[2] = PointInPlane.RotatePoint(aNewRightRectangle[2], aNewRightRectangle[1], aRotationAngle); aNewRightRectangle[3] = PointInPlane.RotatePoint(aNewRightRectangle[3], aNewRightRectangle[1], aRotationAngle); // move to new rectangle position aNewRightRectangle[0] = PointInPlane.MovePoint(aNewRightRectangle[0], aMovingVector); aNewRightRectangle[1] = PointInPlane.MovePoint(aNewRightRectangle[1], aMovingVector); aNewRightRectangle[2] = PointInPlane.MovePoint(aNewRightRectangle[2], aMovingVector); aNewRightRectangle[3] = PointInPlane.MovePoint(aNewRightRectangle[3], aMovingVector); CreateSquare(aNewRightRectangle, fractalColorValuesIn, ref cfvIn, currentIterationIn + 1); } { // left rectangle values computed aRotationAngle = -Math.PI / 4.0; PointInPlane[] aNewLeftRectangle = new PointInPlane[4]; PointInPlane aMovingVector = rectanglePointsIn[3] - rectanglePointsIn[0]; // scale to new rectangle aNewLeftRectangle[0] = rectanglePointsIn[0]; aNewLeftRectangle[1] = PointInPlane.ScalePoint(rectanglePointsIn[0], rectanglePointsIn[1], aScalingCoefficient); aNewLeftRectangle[2] = PointInPlane.ScalePoint(rectanglePointsIn[0], rectanglePointsIn[2], aScalingCoefficient); aNewLeftRectangle[3] = PointInPlane.ScalePoint(rectanglePointsIn[0], rectanglePointsIn[3], aScalingCoefficient); // rotate to new rectangle aNewLeftRectangle[0] = PointInPlane.RotatePoint(aNewLeftRectangle[0], aNewLeftRectangle[0], aRotationAngle); aNewLeftRectangle[1] = PointInPlane.RotatePoint(aNewLeftRectangle[1], aNewLeftRectangle[0], aRotationAngle); aNewLeftRectangle[2] = PointInPlane.RotatePoint(aNewLeftRectangle[2], aNewLeftRectangle[0], aRotationAngle); aNewLeftRectangle[3] = PointInPlane.RotatePoint(aNewLeftRectangle[3], aNewLeftRectangle[0], aRotationAngle); // move to new rectangle position aNewLeftRectangle[0] = PointInPlane.MovePoint(aNewLeftRectangle[0], aMovingVector); aNewLeftRectangle[1] = PointInPlane.MovePoint(aNewLeftRectangle[1], aMovingVector); aNewLeftRectangle[2] = PointInPlane.MovePoint(aNewLeftRectangle[2], aMovingVector); aNewLeftRectangle[3] = PointInPlane.MovePoint(aNewLeftRectangle[3], aMovingVector); CreateSquare(aNewLeftRectangle, fractalColorValuesIn, ref cfvIn, currentIterationIn + 1); } } }
public ComputedFractalValues ReturnComputedFractalValues(RectangleInPlane fractalRectangleIn, int xMaxIn, int yMaxIn, IList <FractalColorValue> fractalColorValuesIn, System.Windows.Forms.ProgressBar fractalProgressIn) { if (fractalColorValuesIn.Count < NumberOfColorUsed) { throw new FractalObserverException("Fractal PythagorasTree needs more colors that are available in the input parameter fractalColorValuesIn!"); } ComputedFractalValues aComputedFractalValues = new ComputedFractalValues(); myZRoots.Clear(); for (int aCurrentYPos = 0; aCurrentYPos < yMaxIn; aCurrentYPos++) { fractalProgressIn.Value = (int)(100.0 * ((double)aCurrentYPos / (double)yMaxIn)); for (int aCurrentXPos = 0; aCurrentXPos < xMaxIn; aCurrentXPos++) { int tempRoot = 0; int tempValue = 0; int n = 0; // initial values myZValues[n].Re = fractalRectangleIn.StartX + Math.Abs(fractalRectangleIn.StartX - fractalRectangleIn.EndX) * ((double)aCurrentXPos / (double)xMaxIn); myZValues[n].Im = fractalRectangleIn.StartY + Math.Abs(fractalRectangleIn.StartY - fractalRectangleIn.EndY) * ((double)aCurrentYPos / (double)yMaxIn); // computation of next values until the maximum iteration count or until the conditions are met do { n++; myZValues[n] = ComplexOperations.Substract(myZValues[n - 1], ComplexOperations.Divide(Equation.ComplexFunctionValue(myZValues[n - 1]), Equation.ComplexFunctionDerivativeValue(myZValues[n - 1]))); } while (((Math.Abs(myZValues[n].Re - myZValues[n - 1].Re) > myTreshold) || (Math.Abs(myZValues[n].Im - myZValues[n - 1].Im) > myTreshold)) && (n < (MaximumNumberOfIterations - 1))); ComputedFractalValue aCFValue = null; FractalColorValue aFractalColorValue; // if the solution did not converge to root, then return zero values if (n >= (MaximumNumberOfIterations - 1) || double.IsNaN(myZValues[n].Re) || double.IsNaN(myZValues[n].Im)) { aCFValue = new ComputedFractalValue(); aFractalColorValue = ReturnColor(tempRoot, tempValue, fractalColorValuesIn); aCFValue.ColorValue = aFractalColorValue; aCFValue.AddComputedPoint(new System.Drawing.Point(aCurrentXPos, aCurrentYPos)); aCFValue.TypeOfShape = TypesOfShape.Point; aCFValue.UsedTypeOfCoordinateSystem = TypesOfCoordinateSystem.Screen; aComputedFractalValues.AddComputedFractalValue(aCFValue); continue; } bool aNewRoot = true; int aRootNumber = 0; // find out if the root is new until now, or if the current root was found already for (int i = 0; i < myZRoots.Count; i++) { if ((Math.Abs(myZRoots[i].Re - myZValues[n].Re) < myTreshold) && (Math.Abs(myZRoots[i].Im - myZValues[n].Im) < myTreshold)) { aNewRoot = false; aRootNumber = i; break; } } // if this root is new until now, add new item to myZRoots List if (aNewRoot) { ComplexNumber aComplexRoot = new ComplexNumber(); aComplexRoot.Re = myZValues[n].Re; aComplexRoot.Im = myZValues[n].Im; myZRoots.Add(aComplexRoot); aRootNumber = myZRoots.Count - 1; } // sets the computed values for this pixel to return structure and return it tempValue = n; if (aRootNumber == 0) { tempRoot = 1; } else if (aRootNumber == 1) { tempRoot = 2; } else if (aRootNumber == 2) { tempRoot = 3; } else { throw new FractalObserverException("Error occured during computation of fractal, wrong number of roots was found!"); } // storing of output of computation aCFValue = new ComputedFractalValue(); aFractalColorValue = ReturnColor(tempRoot, tempValue, fractalColorValuesIn); aCFValue.ColorValue = aFractalColorValue; aCFValue.AddComputedPoint(new System.Drawing.Point(aCurrentXPos, aCurrentYPos)); aCFValue.TypeOfShape = TypesOfShape.Point; aCFValue.UsedTypeOfCoordinateSystem = TypesOfCoordinateSystem.Screen; aComputedFractalValues.AddComputedFractalValue(aCFValue); } } return(aComputedFractalValues); }