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);
            }
        }
예제 #3
0
        // 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);
        }