Пример #1
0
        /*
         * /// <summary>
         * /// Die Oberflächennormalen werden abgerundet.
         * /// </summary>
         * protected void CreateSmoothNormales()
         * {
         *  _normalesSmooth1 = new FloatVec3[pData.Width, pData.Height];
         *  _normalesSmooth2 = new FloatVec3[pData.Width, pData.Height];
         *
         *  // Normieren
         *  for (int i = 0; i < pData.Width; i++)
         *  {
         *      for (int j = 0; j < pData.Height; j++)
         *      {
         *          FloatPixelInfo pInfo = _pictureData.Points[i, j];
         *          if (pInfo != null)
         *          {
         *              // pInfo.Normal.Normalize();
         *              _normalesSmooth1[i, j] = pInfo.Normal;
         *              _normalesSmooth1[i, j].Normalize();
         *          }
         *      }
         *  }
         *
         *  FloatVec3[,] currentSmooth = _normalesSmooth1;
         *  FloatVec3[,] nextSmooth = _normalesSmooth2;
         *  FloatVec3[,] tempSmooth;
         *  float maxDist = _maxPoint.Dist(_minPoint);
         *  float dGlobal = maxDist;
         *  dGlobal /= 1500;
         *
         *  int smoothLevel = (int)_parameters.GetDouble("Renderer.SmoothNormalLevel");
         *  for (int currentSmoothLevel = 0; currentSmoothLevel < smoothLevel; currentSmoothLevel++)
         *  {
         *
         *      // create nextSmooth
         *      for (int i = 0; i < pData.Width; i++)
         *      {
         *          for (int j = 0; j < pData.Height; j++)
         *          {
         *              FloatVec3 center = null;
         *              center = currentSmooth[i, j];
         *              FloatPixelInfo pInfo = _pictureData.Points[i, j];
         *              // Test ohne smooth-Factor
         *              // Nachbarelemente zusammenrechnen
         *              FloatVec3 neighbors = new FloatVec3();
         *              int neighborFound = 0;
         *              for (int k = -1; k <= 1; k++)
         *              {
         *                  for (int l = -1; l <= 1; l++)
         *                  {
         *                      int posX = i + k;
         *                      int posY = j + l;
         *                      if (posX >= 0 && posX < pData.Width && posY >= 0 && posY < pData.Height)
         *                      {
         *                          FloatVec3 currentNormal = null;
         *                          currentNormal = currentSmooth[i + k, j + l];
         *                          FloatPixelInfo pInfo2 = _pictureData.Points[i + k, j + l];
         *
         *                          if (currentNormal != null)
         *                          {
         *                              float amount = 1;
         *                              if (pInfo != null && pInfo2 != null)
         *                              {
         *                                  float dist = pInfo.Coord.Dist(pInfo2.Coord);
         *
         *                                  if (dist < dGlobal)
         *                                      amount = 1.0f;
         *                                  else if (dist > dGlobal && dist < 5.0 * dGlobal)
         *                                      amount = 1.0f - (dGlobal / dist / 5.0f);
         *                                  else
         *                                      amount = 0;
         *                              }
         *
         *                              neighbors.Add(currentNormal.Mult(amount));
         *                              neighborFound++;
         *                          }
         *                      }
         *                  }
         *              }
         *              neighbors.Normalize();
         *              if (center != null)
         *              {
         *                  nextSmooth[i, j] = center;
         *                  if (center != null || neighborFound > 1)
         *                  {
         *                      FloatVec3 center2 = center;
         *                      center2.Mult(200);
         *                      neighbors.Add(center2.Mult(4));
         *                      neighbors.Normalize();
         *                      nextSmooth[i, j] = neighbors;
         *                  }
         *              }
         *              else
         *              {
         *                  if (neighborFound > 4)
         *                  {
         *                      nextSmooth[i, j] = neighbors;
         *                  }
         *              }
         *          }
         *      }
         *
         *      tempSmooth = currentSmooth;
         *      currentSmooth = nextSmooth;
         *      nextSmooth = tempSmooth;
         *
         *  }
         *
         *
         * }
         */


        /// <summary>
        /// Field  _heightMap is created from _pictureData.Points.
        /// </summary>
        protected void CreateHeightMap()
        {
            _heightMap = new float[pData.Width, pData.Height];

            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    FloatPixelInfo pInfo = _pictureData.Points[i, j];
                    if (pInfo != null)
                    {
                        _heightMap[i, j] = pInfo.Coord.Y;
                        if (_minY > pInfo.Coord.Y && pInfo.Coord.Y != 0)
                        {
                            _minY = pInfo.Coord.Y;
                        }
                        if (_maxY < pInfo.Coord.Y)
                        {
                            _maxY = pInfo.Coord.Y;
                        }
                    }
                    else
                    {
                        _heightMap[i, j] = float.MinValue;
                    }
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Creates boundingbox infos.
 /// </summary>
 protected void CreateStatisticInfo()
 {
     _minPoint.X = float.MaxValue;
     _minPoint.Y = float.MaxValue;
     _minPoint.Z = float.MaxValue;
     _maxPoint.X = float.MinValue;
     _maxPoint.Y = float.MinValue;
     _maxPoint.Z = float.MinValue;
     for (int i = 0; i < _pictureData.Width; i++)
     {
         for (int j = 0; j < _pictureData.Height; j++)
         {
             FloatPixelInfo pInfo = _pictureData.Points[i, j];
             if (pInfo != null)
             {
                 FloatVec3 coord = pInfo.Coord;
                 if (coord.X < _minPoint.X)
                 {
                     _minPoint.X = coord.X;
                 }
                 if (coord.Y < _minPoint.Y)
                 {
                     _minPoint.Y = coord.Y;
                 }
                 if (coord.Z < _minPoint.Z)
                 {
                     _minPoint.Z = coord.Z;
                 }
                 if (coord.X > _maxPoint.X)
                 {
                     _maxPoint.X = coord.X;
                 }
                 if (coord.Y > _maxPoint.Y)
                 {
                     _maxPoint.Y = coord.Y;
                 }
                 if (coord.Z > _maxPoint.Z)
                 {
                     _maxPoint.Z = coord.Z;
                 }
             }
         }
     }
 }
        /// <summary>
        /// Initialisation with formula is needed for computing original coordinates.
        /// </summary>
        public override void Init(Formulas formula)
        {
            base.Init(formula);
            // Original data has to scale such that values fits into float range.
            Vec3 minPoint = new Vec3(0, 0, 0);
            Vec3 maxPoint = new Vec3(0, 0, 0);

            minPoint.X = Double.MaxValue;
            minPoint.Y = Double.MaxValue;
            minPoint.Z = Double.MaxValue;
            maxPoint.X = Double.MinValue;
            maxPoint.Y = Double.MinValue;
            maxPoint.Z = Double.MinValue;
            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    PixelInfo pInfo = pData.Points[i, j];
                    if (pInfo != null)
                    {
                        Vec3 coord = formula.GetTransform(pInfo.Coord.X, pInfo.Coord.Y, pInfo.Coord.Z);
                        if (coord.X < minPoint.X)
                        {
                            minPoint.X = coord.X;
                        }
                        if (coord.Y < minPoint.Y)
                        {
                            minPoint.Y = coord.Y;
                        }
                        if (coord.Z < minPoint.Z)
                        {
                            minPoint.Z = coord.Z;
                        }
                        if (coord.X > maxPoint.X)
                        {
                            maxPoint.X = coord.X;
                        }
                        if (coord.Y > maxPoint.Y)
                        {
                            maxPoint.Y = coord.Y;
                        }
                        if (coord.Z > maxPoint.Z)
                        {
                            maxPoint.Z = coord.Z;
                        }
                    }
                }
            }
            Vec3 center = new Vec3(0, 0, 0);

            center.X = (maxPoint.X + minPoint.X) / 2.0;
            center.Y = (maxPoint.Y + minPoint.Y) / 2.0;
            center.Z = (maxPoint.Z + minPoint.Z) / 2.0;
            double radius = maxPoint.X - minPoint.X + maxPoint.Y - minPoint.Y + maxPoint.Z - minPoint.Z;

            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    PixelInfo pInfo = pData.Points[i, j];
                    if (pInfo != null)
                    {
                        FloatPixelInfo floatPixelInfo = new FloatPixelInfo();
                        floatPixelInfo.Coord.X        = (float)((pInfo.Coord.X - center.X) / radius);
                        floatPixelInfo.Coord.Y        = (float)((pInfo.Coord.Y - center.Y) / radius);
                        floatPixelInfo.Coord.Z        = (float)((pInfo.Coord.Z - center.Z) / radius);
                        floatPixelInfo.AdditionalInfo = pInfo.AdditionalInfo;
                        floatPixelInfo.IsInside       = pInfo.IsInside;

                        pInfo.Normal.Normalize();

                        floatPixelInfo.Normal.X   = (float)pInfo.Normal.X;
                        floatPixelInfo.Normal.Y   = (float)pInfo.Normal.Y;
                        floatPixelInfo.Normal.Z   = (float)pInfo.Normal.Z;
                        _pictureData.Points[i, j] = floatPixelInfo;
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Compute field of view.
        /// </summary>
        protected void SmoothPlane()
        {
            _rgbSmoothPlane1 = new FloatVec3[pData.Width, pData.Height];
            _rgbSmoothPlane2 = new FloatVec3[pData.Width, pData.Height];
            int intRange = 3;

            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    _rgbSmoothPlane2[i, j] = _rgbPlane[i, j];
                }
            }
            if (_ambientIntensity == 0)
            {
                //  No field of view defined:
                return;
            }

            // starts with rgbSmoothPlane2
            FloatVec3[,] currentPlane = _rgbSmoothPlane2;
            FloatVec3[,] nextPlane    = _rgbSmoothPlane1;
            // contain the result colors
            FloatVec3[,] resultPlane = _rgbSmoothPlane1;

            for (int m = 0; m < _ambientIntensity; m++)
            {
                if (_stopRequest)
                {
                    return;
                }
                for (int i = 0; i < pData.Width; i++)
                {
                    for (int j = 0; j < pData.Height; j++)
                    {
                        double         neighborsFound = 0;
                        FloatPixelInfo pInfo          = _pictureData.Points[i, j];
                        FloatVec3      nColor         = new FloatVec3();
                        float          ydNormalized   = (float)GetAmbientValue(_heightMap[i, j]);
                        ydNormalized = (float)Math.Sqrt(ydNormalized);
                        intRange     = 1;
                        if (intRange == 0)
                        {
                            nColor         = currentPlane[i, j];
                            neighborsFound = 1;
                        }
                        float sumColor = 0;

                        //           if(pData.Points[i, j]!=null) {
                        //if (true)
                        {
                            for (int k = -intRange; k <= intRange; k++)
                            {
                                for (int l = -intRange; l <= intRange; l++)
                                {
                                    // Center Pixel is also allowed
                                    // if (k != 0 || l != 0) {
                                    int posX = i + k;
                                    int posY = j + l;
                                    if (posX >= 0 && posX < pData.Width && posY >= 0 && posY < pData.Height)
                                    {
                                        FloatVec3 nColor1 = new FloatVec3();
                                        if (true)
                                        //   if ( (ylocalDiff > 0) ||(i==posX && j==posY))
                                        //   if ((ylocalDiff < 0) || (i == posX && j == posY))
                                        //   if(false)
                                        {
                                            //double range = (k * k + l * l) / (intRange * intRange);
                                            int   range = (k * k + l * l);
                                            float mult  = 1;

                                            if (range == 0)
                                            {
                                                // mult = 0.6;
                                                mult = ydNormalized * 0.3f;
                                                //mult = 0.2;
                                            }
                                            if (range == 1)
                                            {
                                                //mult = 0.25;
                                                mult = (1.0f - ydNormalized) * 0.4f;
                                                //mult = 0.45;
                                            }
                                            if (range == 2)
                                            {
                                                //mult=0.15;
                                                mult = (1.0f - ydNormalized) * 0.3f;
                                                //mult = 0.35;
                                            }
                                            // mult += 0.00001;


                                            FloatPixelInfo pInfo2 = _pictureData.Points[posX, posY];

                                            float amount = 1;
                                            if (pInfo != null && pInfo2 != null)
                                            {
                                                float dist = pInfo.Coord.Dist(pInfo2.Coord);

                                                float dGlobal = _maxPoint.Dist(_minPoint);
                                                dGlobal /= 1500;
                                                if (dist < dGlobal)
                                                {
                                                    amount = 1.0f;
                                                }
                                                else
                                                {
                                                    //  else if (dist > dGlobal && dist < 10.0 * dGlobal)
                                                    amount = 1.0f - (dGlobal / dist) / 10.0f;
                                                }
                                                // else
                                                //     amount = 0.0;
                                            }

                                            mult *= amount;
                                            //  mult *= 1.0/ydNormalized;


                                            sumColor += mult;

                                            FloatVec3 currentColor = currentPlane[posX, posY];
                                            nColor1.X = currentColor.X;
                                            nColor1.Y = currentColor.Y;
                                            nColor1.Z = currentColor.Z;
                                            nColor1   = nColor1.Mult(mult); // Scaling;

                                            nColor.Add(nColor1);
                                            neighborsFound++;
                                        }
                                    }
                                }
                            }
                        }

                        if (neighborsFound > 1)
                        {
                            nColor = nColor.Mult(1 / sumColor);
                        }
                        else
                        {
                            nColor = currentPlane[i, j];
                        }
                        nextPlane[i, j] = nColor;
                    }
                }

                resultPlane  = nextPlane;
                nextPlane    = currentPlane;
                currentPlane = resultPlane;
            }

            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    _rgbPlane[i, j] = resultPlane[i, j];
                }
            }

            _rgbSmoothPlane1 = null;
            _rgbSmoothPlane2 = null;

            return;
        }
Пример #5
0
        /// <summary>
        /// Get the color information of the bitmap at (x,y)
        /// </summary>
        protected Vec3 GetRgb(int x, int y)
        {
            FloatVec3      retVal = new FloatVec3(0, 0, 1); // blau
            FloatPixelInfo pInfo  = _pictureData.Points[x, y];

            if (pInfo == null)
            {
                return(new Vec3(_backColorRed, _backColorGreen, _backColorBlue));
            }

            FloatVec3 light  = new FloatVec3(0, 0, 0);
            FloatVec3 normal = null;

            normal = pInfo.Normal;
            if (normal == null)
            {
                return(new Vec3(0, 0, 0));
            }

            normal.Normalize();

            if (pInfo.Normal != null)
            {
                light = GetLightF(normal);
            }

            retVal.X = light.X;
            retVal.Y = light.Y;
            retVal.Z = light.Z;


            retVal.X = (float)(_lightIntensity * retVal.X + (1 - _lightIntensity) * (1 - _shadowPlane[x, y]));
            retVal.Y = (float)(_lightIntensity * retVal.Y + (1 - _lightIntensity) * (1 - _shadowPlane[x, y]));
            retVal.Z = (float)(_lightIntensity * retVal.Z + (1 - _lightIntensity) * (1 - _shadowPlane[x, y]));

            if (retVal.X < 0)
            {
                retVal.X = 0;
            }
            if (retVal.Y < 0)
            {
                retVal.Y = 0;
            }
            if (retVal.Z < 0)
            {
                retVal.Z = 0;
            }

            if (retVal.X > 1)
            {
                retVal.X = 1;
            }
            if (retVal.Y > 1)
            {
                retVal.Y = 1;
            }
            if (retVal.Z > 1)
            {
                retVal.Z = 1;
            }

            float brightLightLevel = (float)_parameters.GetDouble("Renderer.BrightLightLevel");

            if (brightLightLevel > 0)
            {
                retVal.X = (1 - brightLightLevel) * retVal.X + brightLightLevel * light.X * (1 - _shadowPlane[x, y]);
                retVal.Y = (1 - brightLightLevel) * retVal.Y + brightLightLevel * light.Y * (1 - _shadowPlane[x, y]);
                retVal.Z = (1 - brightLightLevel) * retVal.Z + brightLightLevel * light.Z * (1 - _shadowPlane[x, y]);
            }

            if (retVal.X < 0)
            {
                retVal.X = 0;
            }
            if (retVal.Y < 0)
            {
                retVal.Y = 0;
            }
            if (retVal.Z < 0)
            {
                retVal.Z = 0;
            }

            if (retVal.X > 1)
            {
                retVal.X = 1;
            }
            if (retVal.Y > 1)
            {
                retVal.Y = 1;
            }
            if (retVal.Z > 1)
            {
                retVal.Z = 1;
            }

            // Add surface color
            bool useAdditionalColorinfo = true;

            if (_colorIntensity <= 0)
            {
                useAdditionalColorinfo = false;
            }

            if (useAdditionalColorinfo && ((pInfo.IsInside && _colorInside) || (!pInfo.IsInside && _colorOutside)))
            {
                if (pInfo != null && pInfo.AdditionalInfo != null)
                {
                    if (double.IsNaN(pInfo.AdditionalInfo.red))
                    {
                        pInfo.AdditionalInfo.red = 0;
                    }
                    if (double.IsNaN(pInfo.AdditionalInfo.green))
                    {
                        pInfo.AdditionalInfo.green = 0;
                    }
                    if (double.IsNaN(pInfo.AdditionalInfo.blue))
                    {
                        pInfo.AdditionalInfo.blue = 0;
                    }

                    if (pInfo.AdditionalInfo.red < 0)
                    {
                        pInfo.AdditionalInfo.green -= pInfo.AdditionalInfo.red;
                        pInfo.AdditionalInfo.blue  -= pInfo.AdditionalInfo.red;
                        pInfo.AdditionalInfo.red    = 0;
                    }
                    if (pInfo.AdditionalInfo.green < 0)
                    {
                        pInfo.AdditionalInfo.red  -= pInfo.AdditionalInfo.green;
                        pInfo.AdditionalInfo.blue -= pInfo.AdditionalInfo.green;
                        pInfo.AdditionalInfo.green = 0;
                    }
                    if (pInfo.AdditionalInfo.blue < 0)
                    {
                        pInfo.AdditionalInfo.red  -= pInfo.AdditionalInfo.blue;
                        pInfo.AdditionalInfo.blue -= pInfo.AdditionalInfo.blue;
                        pInfo.AdditionalInfo.blue  = 0;
                    }


                    // Normalise;
                    float r1 = (float)(_colorFactorRed * Math.Pow(pInfo.AdditionalInfo.red, _colorIntensity));
                    float g1 = (float)(_colorFactorGreen * Math.Pow(pInfo.AdditionalInfo.green, _colorIntensity));
                    float b1 = (float)(_colorFactorBlue * Math.Pow(pInfo.AdditionalInfo.blue, _colorIntensity));
                    if (r1 < 0)
                    {
                        r1 = -r1;
                    }
                    if (g1 < 0)
                    {
                        g1 = -g1;
                    }
                    if (b1 < 0)
                    {
                        b1 = -b1;
                    }

                    // Normalize:
                    float norm = (float)(Math.Sqrt(r1 * r1 + g1 * g1 + b1 * b1) / Math.Sqrt(2.5));
                    if (norm > 0)
                    {
                        r1 = r1 / norm;
                        g1 = g1 / norm;
                        b1 = b1 / norm;

                        if (_colorThreshold > 0)
                        {
                            double thresholdIndicator   = Math.Max(Math.Abs(r1 - b1), Math.Max(Math.Abs(r1 - g1), Math.Abs(g1 - b1)));
                            float  lowerThresholdFactor = (float)0.7;
                            if (thresholdIndicator < _colorThreshold * lowerThresholdFactor)
                            {
                                r1 = (float)1;
                                g1 = (float)1;
                                b1 = (float)1;
                            }
                            else if (thresholdIndicator < _colorThreshold)
                            {
                                r1 = (float)(_colorThreshold - thresholdIndicator) * (float)0.5 / lowerThresholdFactor + r1;
                                g1 = (float)(_colorThreshold - thresholdIndicator) * (float)0.5 / lowerThresholdFactor + g1;
                                b1 = (float)(_colorThreshold - thresholdIndicator) * (float)0.5 / lowerThresholdFactor + b1;
                            }
                        }
                    }

                    for (int i = 0; i < 5; i++)
                    {
                        if (r1 > 1)
                        {
                            b1 += (r1 - 1) / (float)2.0;
                            g1 += (r1 - 1) / (float)2.0;
                            r1  = 1;
                        }
                        if (b1 > 1)
                        {
                            r1 += (b1 - 1) / (float)2.0;
                            g1 += (b1 - 1) / (float)2.0;
                            b1  = 1;
                        }
                        if (g1 > 1)
                        {
                            r1 += (g1 - 1) / (float)2.0;
                            b1 += (g1 - 1) / (float)2.0;
                            g1  = 1;
                        }
                    }

                    if (r1 > 1)
                    {
                        r1 = 1;
                    }
                    if (b1 > 1)
                    {
                        b1 = 1;
                    }
                    if (g1 > 1)
                    {
                        g1 = 1;
                    }

                    if (_colorGreyness > 0)
                    {
                        r1 = (float)(_colorGreyness + (1 - _colorGreyness) * r1);
                        g1 = (float)(_colorGreyness + (1 - _colorGreyness) * g1);
                        b1 = (float)(_colorGreyness + (1 - _colorGreyness) * b1);
                    }

                    if (r1 > 1)
                    {
                        r1 = 1;
                    }
                    if (b1 > 1)
                    {
                        b1 = 1;
                    }
                    if (g1 > 1)
                    {
                        g1 = 1;
                    }

                    if (norm != 0)
                    {
                        switch (_rgbType)
                        {
                        case 1:
                            retVal.X *= r1;
                            retVal.Y *= g1;
                            retVal.Z *= b1;
                            break;

                        case 2:
                            retVal.X *= r1;
                            retVal.Y *= b1;
                            retVal.Z *= g1;
                            break;

                        case 3:
                            retVal.X *= g1;
                            retVal.Y *= r1;
                            retVal.Z *= b1;
                            break;

                        case 4:
                            retVal.X *= g1;
                            retVal.Y *= b1;
                            retVal.Z *= r1;
                            break;

                        case 5:
                            retVal.X *= b1;
                            retVal.Y *= r1;
                            retVal.Z *= g1;
                            break;

                        case 6:
                            retVal.X *= b1;
                            retVal.Y *= g1;
                            retVal.Z *= r1;
                            break;

                        default:
                            retVal.X *= r1;
                            retVal.Y *= g1;
                            retVal.Z *= b1;
                            break;
                        }
                    }
                }
            }

            if (_contrast != 1)
            {
                retVal.X = (float)Math.Pow(retVal.X, _contrast);
                retVal.Y = (float)Math.Pow(retVal.Y, _contrast);
                retVal.Z = (float)Math.Pow(retVal.Z, _contrast);
            }

            if (_brightness > 1)
            {
                retVal.X *= _brightness;
                retVal.Y *= _brightness;
                retVal.Z *= _brightness;
            }

            if (retVal.X < 0)
            {
                retVal.X = 0;
            }
            if (retVal.X > 1)
            {
                retVal.X = 1;
            }
            if (retVal.Y < 0)
            {
                retVal.Y = 0;
            }
            if (retVal.Z < 0)
            {
                retVal.Z = 0;
            }
            if (retVal.Y > 1)
            {
                retVal.Y = 1;
            }
            if (retVal.Z > 1)
            {
                retVal.Z = 1;
            }

            if (pInfo != null && pInfo.AdditionalInfo != null)
            {
                pInfo.AdditionalInfo.red2   = retVal.X;
                pInfo.AdditionalInfo.green2 = retVal.Y;
                pInfo.AdditionalInfo.blue2  = retVal.Z;
            }

            return(new Vec3(retVal.X, retVal.Y, retVal.Z));
        }
Пример #6
0
        /// <summary>
        /// Initialisation with formula is needed for computing original coordinates.
        /// </summary>
        public override void Init(Formulas formula)
        {
            base.Init(formula);
            // Original data has to scale such that values fits into float range.
            Vec3 minPoint = new Vec3(0, 0, 0);
            Vec3 maxPoint = new Vec3(0, 0, 0);
            minPoint.X = Double.MaxValue;
            minPoint.Y = Double.MaxValue;
            minPoint.Z = Double.MaxValue;
            maxPoint.X = Double.MinValue;
            maxPoint.Y = Double.MinValue;
            maxPoint.Z = Double.MinValue;
            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    PixelInfo pInfo = pData.Points[i, j];
                    if (pInfo != null)
                    {
                        Vec3 coord = formula.GetTransform(pInfo.Coord.X, pInfo.Coord.Y, pInfo.Coord.Z);
                        if (coord.X < minPoint.X)
                            minPoint.X = coord.X;
                        if (coord.Y < minPoint.Y)
                            minPoint.Y = coord.Y;
                        if (coord.Z < minPoint.Z)
                            minPoint.Z = coord.Z;
                        if (coord.X > maxPoint.X)
                            maxPoint.X = coord.X;
                        if (coord.Y > maxPoint.Y)
                            maxPoint.Y = coord.Y;
                        if (coord.Z > maxPoint.Z)
                            maxPoint.Z = coord.Z;
                    }
                }
            }
            Vec3 center = new Vec3(0, 0, 0);
            center.X = (maxPoint.X + minPoint.X) / 2.0;
            center.Y = (maxPoint.Y + minPoint.Y) / 2.0;
            center.Z = (maxPoint.Z + minPoint.Z) / 2.0;
            double radius = maxPoint.X - minPoint.X + maxPoint.Y - minPoint.Y + maxPoint.Z - minPoint.Z;

            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    PixelInfo pInfo = pData.Points[i, j];
                    if (pInfo != null)
                    {
                        FloatPixelInfo floatPixelInfo = new FloatPixelInfo();
                        floatPixelInfo.Coord.X = (float)((pInfo.Coord.X - center.X) / radius);
                        floatPixelInfo.Coord.Y = (float)((pInfo.Coord.Y - center.Y) / radius);
                        floatPixelInfo.Coord.Z = (float)((pInfo.Coord.Z - center.Z) / radius);
                        floatPixelInfo.AdditionalInfo = pInfo.AdditionalInfo;
                        floatPixelInfo.IsInside = pInfo.IsInside;

                        pInfo.Normal.Normalize();

                        floatPixelInfo.Normal.X = (float)pInfo.Normal.X;
                        floatPixelInfo.Normal.Y = (float)pInfo.Normal.Y;
                        floatPixelInfo.Normal.Z = (float)pInfo.Normal.Z;
                        _pictureData.Points[i, j] = floatPixelInfo;
                    }
                }
            }
        }