RayCastAt() 공개 메소드

Copy of fixpoint (no normals are computed).
public RayCastAt ( long zykl, double x, double y, double z, double zz, double xd, double yd, double zd, double zzd, double wix, double wiy, double wiz, double jx, double jy, double jz, double jzz, int formula, bool invers, int pixelX, int pixelY, bool use4Points ) : double
zykl long
x double
y double
z double
zz double
xd double
yd double
zd double
zzd double
wix double
wiy double
wiz double
jx double
jy double
jz double
jzz double
formula int
invers bool
pixelX int
pixelY int
use4Points bool
리턴 double
예제 #1
0
        /// <summary>
        /// Compute surface data.
        /// </summary>
        protected void Generate(FracValues act_val, int zyklen, double screensize, int formula, bool perspective)
        {
            Random rand = new Random();
            _maxUpdateSteps = ParameterDict.Current.GetInt("View.UpdateSteps");
            double[] col = null;
            double xd, yd, zd;
            double x, y, z;
            double dephAdd = ParameterDict.Current.GetInt("View.DephAdd") * screensize;
            act_val = act_val.Clone();
            Formulas formulas = new Formulas(_pData);
            _lastUsedFormulas = formulas;
            if (ParameterDict.Current["Intern.Formula.Source"].Trim() == "")
            {
                formulas.InternFormula = new Fractrace.TomoGeometry.VecRotMandel2d();
            }
            else
            {
                Fractrace.TomoGeometry.TomoFormulaFactory fac = new Fractrace.TomoGeometry.TomoFormulaFactory();
                formulas.InternFormula = fac.CreateFromString(ParameterDict.Current["Intern.Formula.Source"]);
            }
            if (formulas.InternFormula == null)
                return;
            formulas.InternFormula.Init();

            double centerX = ParameterDict.Current.GetDouble("Scene.CenterX");
            double centerY = ParameterDict.Current.GetDouble("Scene.CenterY");
            double centerZ = ParameterDict.Current.GetDouble("Scene.CenterZ");

            Rotation rotView = new Rotation();
            rotView.Init(centerX, centerY, centerZ, ParameterDict.Current.GetDouble("Transformation.Camera.AngleX"), ParameterDict.Current.GetDouble("Transformation.Camera.AngleY"),
                ParameterDict.Current.GetDouble("Transformation.Camera.AngleZ"));
            formulas.Transforms.Add(rotView);

            // TODO: only use in compatibility mode.
            Rotation rot = new Rotation();
            rot.Init();
            formulas.Transforms.Add(rot);

            if (_isRightView)
            {
                RightEyeView stereoTransform = new RightEyeView();
                stereoTransform.Init();
                formulas.Transforms.Add(stereoTransform);
            }

            col = formulas.col;
            _maxxIter = _width;
            _maxyIter = (int)(ParameterDict.Current.GetDouble("View.Deph") * screensize);
            if(IsSmallPreview())
                _maxyIter = _maxxIter;
            _maxzIter = _height;

            int MINX_ITER = 0;
            int MINY_ITER = 0;
            int MINZ_ITER = 0;
            double fa1;
            int xschl = 0, yschl = 0, zschl = 0, xx = 0, yy = 0;
            double wix = 0, wiy = 0, wiz = 0;
            double jx = 0, jy = 0, jz = 0, jzz = 0;

            jx = ParameterDict.Current.GetDouble("Formula.Static.jx");
            jy = ParameterDict.Current.GetDouble("Formula.Static.jy");
            jz = ParameterDict.Current.GetDouble("Formula.Static.jz");
            jzz = ParameterDict.Current.GetDouble("Formula.Static.jzz");

            // Innenbereich
            int minCycle = (int)ParameterDict.Current.GetDouble("Formula.Static.MinCycle");
            if (minCycle == 0)
                minCycle = zyklen;

            // Offset für den Maximalzyklus für die klassische 2D-Darstellung
            int cycleAdd = 128;

            wix = act_val.arc.x;
            wiy = act_val.arc.y;
            wiz = act_val.arc.z;

            xd = (act_val.end_tupel.x - act_val.start_tupel.x) / (_maxxIter - MINX_ITER);
            yd = (act_val.end_tupel.y - act_val.start_tupel.y) / (_maxyIter - MINY_ITER);
            zd = (act_val.end_tupel.z - act_val.start_tupel.z) / (_maxzIter - MINZ_ITER);

            if (_oldData != null)
            {
                yd = yd / (_updateCount);
                if (_updateCount < 5)
                {
                    _maxyIter *= _updateCount;
                }
            }
            if (_transformUpdate)
            {
                yd *= 3.0;
            }

            double xcenter = (act_val.start_tupel.x + act_val.end_tupel.x) / 2.0;
            double ycenter = (act_val.start_tupel.y + act_val.end_tupel.y) / 2.0;
            double zcenter = (act_val.start_tupel.z + act_val.end_tupel.z) / 2.0;
            bool isYborder = true;

            // Projektion initialisieren und der Berechnung zuordnen:
            // TODO: Projektion über Einstellungen abwählbar machen
            double cameraDeph = act_val.end_tupel.y - act_val.start_tupel.y;
            cameraDeph *= ParameterDict.Current.GetDouble("Transformation.Perspective.Cameraposition");
            Vec3 camera = new Vec3(xcenter, act_val.end_tupel.y + cameraDeph, zcenter);
            Vec3 viewPoint = new Vec3(xcenter, act_val.end_tupel.y, zcenter);
            Projection proj = new Projection(camera, viewPoint);
            if (ParameterDict.Current.GetBool("View.Perspective"))
                formulas.Projection = proj;

            // Bei der Postererstellung werden die Parameter der räumlichen Projektion auf das mittlere Bild
            // ausgerichtet und anschließend die Grenzen verschoben
            double xPoster = ParameterDict.Current.GetInt("View.PosterX");
            double zPoster = ParameterDict.Current.GetInt("View.PosterZ");

            double xDiff = act_val.end_tupel.x - act_val.start_tupel.x;
            double zDiff = act_val.end_tupel.z - act_val.start_tupel.z;
            act_val.end_tupel.x += xDiff * xPoster;
            act_val.start_tupel.x += xDiff * xPoster;
            act_val.end_tupel.z += zDiff * zPoster;
            act_val.start_tupel.z += zDiff * zPoster;

            // Start der Iteration in der Reihenfolge: z,x,y (y entspricht der Tiefe)
            z = act_val.end_tupel.z + zd;

            for (zschl = (int)(_maxzIter); zschl >= (MINZ_ITER); zschl -= 1)
            {

                // Nur wenn der Scheduler die Erlaubnis gibt, zschl zu benutzen,
                // die Berechnung ausführen (sonst nächste Iteration)
                if (IsAvailable(_maxzIter - zschl))
                {

                    System.Windows.Forms.Application.DoEvents();
                    z = act_val.end_tupel.z - (double)zd * (_maxzIter - zschl);

                    bool minYDetected = false;
                    for (xschl = (int)(MINX_ITER); xschl <= _maxxIter; xschl += 1)
                    {
                        if (_abort)
                        {
                            return;
                        }

                        x = act_val.start_tupel.x + (double)xd * xschl;
                        double miny = 0;
                        isYborder = true;

                        xx = xschl;
                        yy = _maxzIter - zschl;
                        if (double.IsNaN(x) )
                            return ;

                        // Used for better start values in update iteration
                        double yAdd = rand.NextDouble() * yd;
                        // In last computation a voxel ist found at (xx,zz)
                        bool centerIsSet = false;
                        // In last computation at least on voxel ist found near (xx,zz)
                        bool areaIsSet = false;
                        double yAddCenter = 0;

                        bool needComputing = true;
                        if (_oldPictureData != null)
                        {
                            needComputing = false;
                            PixelInfo pxInfoTest = _oldPictureData.Points[xx, yy];
                            if (pxInfoTest != null && pxInfoTest.Coord != null)
                            {
                                yAddCenter = pxInfoTest.Coord.Y;
                                yAdd = yAddCenter;
                                centerIsSet = true;
                            }

                            for (int xxi = -1; xxi <= 1; xxi++)
                            {
                                for (int yyi = -1; yyi <= 1; yyi++)
                                {
                                    int xxposi = xx + xxi;
                                    int yyposi = yy + yyi;
                                    if (xxposi >= 0 && xxposi <= _maxxIter && yyposi >= 0 && yyposi <= _maxzIter)
                                    {
                                        PixelInfo pxInfo = _oldPictureData.Points[xxposi, yyposi];
                                        if (pxInfo != null && pxInfo.Coord != null)
                                        {
                                            areaIsSet = true;
                                            double yAddTemp = pxInfo.Coord.Y;
                                            if (yAdd < yAddTemp || !centerIsSet)
                                                yAdd = yAddTemp;
                                        }
                                    }
                                }
                            }
                        }

                        if (yAdd + yd < act_val.end_tupel.y)
                        {
                            if (centerIsSet)
                            {
                                if (yAddCenter + 4.0 * yd < yAdd)
                                {
                                    needComputing = true;
                                    yAdd = yAdd - act_val.end_tupel.y + 2.0 * ((double)_updateCount) * yd + rand.NextDouble() * yd;
                                    _gData.Picture[xx, yy] = _oldData.Picture[xx, yy];
                                }
                            }
                            else
                            {
                                if (areaIsSet)
                                {
                                    needComputing = true;
                                    yAdd = rand.NextDouble() * yd;
                                }
                            }
                        }

                        if (needComputing)
                        {
                            // yadd cannot be easy handled (because of inside rendering).
                            for (yschl = (int)(_maxyIter); yschl >= MINY_ITER - dephAdd; yschl -= 1)
                            {
                                if (_abort)
                                    return;

                                if (xx >= 0 && xx < _width && yy >= 0 && yy < _height)
                                {
                                    if ((_gData.Picture)[xx, yy] == 0 || (_gData.Picture)[xx, yy] == 2)
                                    { // aha, noch zeichnen
                                        // Test, ob Schnitt mit Begrenzung vorliegt
                                        y = act_val.end_tupel.y - (double)yd * (_maxyIter - yschl);
                                        y += yAdd;
                                        if (double.IsNaN(x) || double.IsNaN(y) || double.IsNaN(z))
                                            return;

                                        fa1 = 0;

                                        int usedCycles = 0;
                                        bool inverse = false;
                                        if (_gData == null)
                                        {
                                            System.Diagnostics.Debug.WriteLine("Error: GData == null");
                                            return;
                                        }
                                        if ((_gData.Picture)[xx, yy] == 0)
                                            usedCycles = formulas.Rechne(x, y, z, 0, zyklen,
                                                  wix, wiy, wiz,
                                                  jx, jy, jz, jzz, formula, inverse);

                                        if ((_gData.Picture)[xx, yy] == 2)
                                        {// Inverse computing
                                            inverse = true;
                                            usedCycles = formulas.Rechne(x, y, z, 0, minCycle,
                                                  wix, wiy, wiz,
                                                  jx, jy, jz, jzz, formula, inverse);
                                        }

                                        if (usedCycles == 0)
                                        {
                                            if (!minYDetected)
                                                miny = yschl;
                                            minYDetected = true;
                                            // Iteration ist nicht abgebrochen, also weiterrechnen:
                                            int oldPictureInfo = (_gData.Picture)[xx, yy]; // pictureInfo wird eventuell zurückgesetzt, wenn
                                            // die Farbberechnung wiederholt wird.

                                            _gData.Picture[xx, yy] = 1; // Punkt als gesetzt markieren
                                            VoxelInfo vInfo = new VoxelInfo();
                                            _gData.PointInfo[xx, yy] = vInfo;
                                            vInfo.i = x;
                                            vInfo.j = y;
                                            vInfo.k = z;

                                            cycleAdd = 1024;
                                            if (minCycle >= 0)
                                            {
                                                cycleAdd = minCycle - zyklen;
                                            }
                                            if (isYborder)
                                            { // es liegt Schnitt mit Begrenzung vor

                                                fa1 = formulas.Rechne(x, y, z, 0, zyklen + cycleAdd,
                                                 wix, wiy, wiz,
                                                 jx, jy, jz, jzz, formula, false);

                                                if (fa1 == 0)
                                                {
                                                    fa1 = -1;
                                                    (_gData.Picture)[xx, yy] = 2; // Punkt nicht als gesetzt markieren
                                                }
                                                else
                                                    fa1 = 255 * fa1 / (zyklen + cycleAdd);

                                                // debug only: alle Farbwerte auf 1 setzen
                                                col[0] = col[1] = col[2] = col[3] = 255;
                                            }
                                            else
                                            {// innerer Punkt

                                                if (inverse)
                                                {

                                                        if (IsSmallPreview())
                                                        {
                                                            fa1 = formulas.RayCastAt(minCycle, x, y, z, 0,
                                                           xd, yd, zd, 0,
                                                           wix, wiy, wiz,
                                                           jx, jy, jz, jzz, formula, inverse, xx, yy, true);
                                                        }
                                                        else
                                                        {
                                                            fa1 = formulas.FixPoint(minCycle, x, y, z, 0,
                                                           xd, yd, zd, 0,
                                                           wix, wiy, wiz,
                                                           jx, jy, jz, jzz, formula, inverse, xx, yy, true);
                                                        }
                                                }
                                                else
                                                {
                                                        if (IsSmallPreview())
                                                        {
                                                            fa1 = formulas.RayCastAt(zyklen, x, y, z, 0,
                                   xd, yd, zd, 0,
                                   wix, wiy, wiz,
                                   jx, jy, jz, jzz, formula, inverse, xx, yy, true);
                                                        }
                                                        else
                                                        {
                                                            fa1 = formulas.FixPoint(zyklen, x, y, z, 0,
                                     xd, yd, zd, 0,
                                     wix, wiy, wiz,
                                     jx, jy, jz, jzz, formula, inverse, xx, yy, true);
                                                            fa1 = (col[0] + col[1] + col[2] + col[3]) / 4.0;
                                                        }
                                                }
                                            }
                                        }
                                    }
                                }
                                isYborder = false;
                            }
                            if ((_gData.Picture)[xx, yy] == 0 || (_gData.Picture)[xx, yy] == 2)
                            {
                                if (_oldPictureData != null)
                                {
                                    _pData.Points[xx, yy] = _oldPictureData.Points[xx, yy];
                                }
                            }

                            if (_oldData != null && _updateCount > 2)
                            {
                                if (_oldPictureData.Points[xx, yy] != null)
                                {
                                    if (_pData.Points[xx, yy] == null)
                                    {
                                        _pData.Points[xx, yy] = _oldPictureData.Points[xx, yy];
                                    }
                                    else
                                    {
                                        if (_pData.Points[xx, yy].Coord.Y < _oldPictureData.Points[xx, yy].Coord.Y)
                                        {
                                            _pData.Points[xx, yy] = _oldPictureData.Points[xx, yy];
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Get the old values:
                            _pData.Points[xx, yy] = _oldPictureData.Points[xx, yy];
                        }
                    }
                }
            }
        }