Пример #1
0
 /// <summary>
 /// Returns the Cross Product of two vectors lhs and rhs
 /// </summary>
 /// <param name="lhs">Vector, the first input vector</param>
 /// <param name="rhs">Vector, the second input vector</param>
 /// <returns>A FloatVector3 containing the cross product of lhs and V</returns>
 public static FloatVector3 operator ^(FloatVector3 lhs, FloatVector3 rhs)
 {
     FloatVector3 Result = new FloatVector3();
     Result.X = (lhs.Y * rhs.Z - lhs.Z * rhs.Y);
     Result.Y = (lhs.Z * rhs.X - lhs.X * rhs.Z);
     Result.Z = (lhs.X * rhs.Y - lhs.Y * rhs.X);
     return Result;
 }
Пример #2
0
 /// <summary>
 /// Divides the components of vector lhs by the respective components
 /// ov vector V and returns the resulting vector. 
 /// </summary>
 /// <param name="lhs">FloatVector3 Dividend (Numbers to be divided)</param>
 /// <param name="rhs">FloatVector3 Divisor (Numbers to divide by)</param>
 /// <returns>A FloatVector3 quotient of lhs and V</returns>
 /// <remarks>To prevent divide by 0, if a 0 is in V, it will return 0 in the result</remarks>
 public static FloatVector3 operator /(FloatVector3 lhs, FloatVector3 rhs)
 {
     FloatVector3 result = new FloatVector3();
     if (rhs.X > 0) result.X = lhs.X / rhs.X;
     if (rhs.Y > 0) result.Y = lhs.Y / rhs.Y;
     if (rhs.Z > 0) result.Z = lhs.Z / rhs.Z;
     return result;
 }
Пример #3
0
 /// <summary>
 /// Multiplies all the scalar members of the the two vectors
 /// </summary>
 /// <param name="lhs">Left hand side</param>
 /// <param name="rhs">Right hand side</param>
 /// <returns></returns>
 public static float Dot(FloatVector3 lhs, FloatVector3 rhs)
 {
     return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z;
 }
Пример #4
0
 /// <summary>
 /// Multiplies the source vector by a scalar.
 /// </summary>
 /// <param name="source"></param>
 /// <param name="scalar"></param>
 /// <returns></returns>
 public static FloatVector3 Multiply(FloatVector3 source, float scalar)
 {
     return new FloatVector3(source.X * scalar, source.Y * scalar, source.Z * scalar);
 }
Пример #5
0
 /// <summary>
 /// Subtracts the specified value
 /// </summary>
 /// <param name="vector">A FloatVector3</param>
 public void Subtract(FloatVector3 vector)
 {
     X -= vector.X;
     Y -= vector.Y;
     Z -= vector.Z;
 }
Пример #6
0
 /// <summary>
 /// Returns the Cross Product of two vectors lhs and V
 /// </summary>
 /// <param name="lhs">Vector, the first input vector</param>
 /// <param name="rhs">Vector, the second input vector</param>
 /// <returns>A FloatVector3 containing the cross product of lhs and V</returns>
 public static FloatVector3 CrossProduct(FloatVector3 lhs, FloatVector3 rhs)
 {
     FloatVector3 result = new FloatVector3();
     result.X = (lhs.Y * rhs.Z - lhs.Z * rhs.Y);
     result.Y = (lhs.Z * rhs.X - lhs.X * rhs.Z);
     result.Z = (lhs.X * rhs.Y - lhs.Y * rhs.X);
     return result;
 }
Пример #7
0
 /// <summary>
 /// Subtracts all the scalar members of the the two vectors
 /// </summary>
 /// <param name="lhs">Left hand side</param>
 /// <param name="rhs">Right hand side</param>
 /// <returns></returns>
 public static FloatVector3 Subtract(FloatVector3 lhs, FloatVector3 rhs)
 {
     return new FloatVector3(lhs.X - rhs.X, lhs.Y - rhs.Y, lhs.Z - rhs.Z);
 }
Пример #8
0
 /// <summary>
 /// Adds the specified v
 /// </summary>
 /// <param name="vector">A FloatVector3 to add to this vector</param>
 public void Add(FloatVector3 vector)
 {
     X += vector.X;
     Y += vector.Y;
     Z += vector.Z;
 }
Пример #9
0
 /// <summary>
 /// Adds all the scalar members of the the two vectors
 /// </summary>
 /// <param name="lhs">Left hand side</param>
 /// <param name="rhs">Right hand side</param>
 /// <returns></returns>
 public static FloatVector3 Add(FloatVector3 lhs, FloatVector3 rhs)
 {
     return new FloatVector3(lhs.X + rhs.X, lhs.Y + rhs.Y, lhs.Z + rhs.Z);
 }
Пример #10
0
        /// <summary>
        /// Create Hillshade of values ranging from 0 to 1, or -1 for no-data regions.  
        /// This should be a little faster since we are accessing the Data field directly instead of working 
        /// through a value parameter.
        /// </summary>
        /// <param name="raster">The raster to create the hillshade from.</param>
        /// <param name="shadedRelief">An implementation of IShadedRelief describing how the hillshade should be created.</param>
        /// <param name="progressHandler">An implementation of IProgressHandler for progress messages</param>
        public static float[][] CreateHillShade(this IRaster raster, IShadedRelief shadedRelief, IProgressHandler progressHandler)
        {
           
            int numCols = raster.NumColumns;
            int numRows = raster.NumRows;
            double noData = raster.NoDataValue;
            float extrusion = shadedRelief.Extrusion;
            float elevationFactor = shadedRelief.ElevationFactor;
            float lightIntensity = shadedRelief.LightIntensity;
            float ambientIntensity = shadedRelief.AmbientIntensity;
            FloatVector3 lightDirection = shadedRelief.GetLightDirection();
           


            float[] aff = new float[6]; // affine coefficients converted to float format
            for (int i = 0; i < 6; i++)
            {
                aff[i] = Convert.ToSingle(raster.Bounds.AffineCoefficients[i]);
            }
            float[][] hillshade = new float[numRows][];

            ProgressMeter pm = new ProgressMeter(progressHandler, MessageStrings.CreatingShadedRelief, numRows);
            for (int row = 0; row < numRows; row++)
            {
                hillshade[row] = new float[numCols];

                for (int col = 0; col < numCols; col++)
                {
                    // 3D position vectors of three points to create a triangle.
                    FloatVector3 v1 = new FloatVector3(0f, 0f, 0f);
                    FloatVector3 v2 = new FloatVector3(0f, 0f, 0f);
                    FloatVector3 v3 = new FloatVector3(0f, 0f, 0f);

                    double val = raster.Value[row, col];
                    // Cannot compute polygon ... make the best guess
                    if (col >= numCols - 1 || row <= 0)
                    {
                        if (col >= numCols - 1 && row <= 0)
                        {
                            v1.Z = (float)val;
                            v2.Z = (float)val;
                            v3.Z = (float)val;
                        }
                        else if (col >= numCols - 1)
                        {
                            v1.Z = (float)raster.Value[row, col - 1];        // 3 - 2
                            v2.Z = (float)raster.Value[row - 1, col];        // | /
                            v3.Z = (float)raster.Value[row - 1, col - 1];    // 1   *
                        }
                        else if (row <= 0)
                        {
                            v1.Z = (float)raster.Value[row + 1, col];         //  3* 2
                            v2.Z = (float)raster.Value[row, col + 1];         //  | /
                            v3.Z = (float)val;                         //  1
                        }
                    }
                    else
                    {
                        v1.Z = (float)val;                              //  3 - 2
                        v2.Z = (float)raster.Value[row - 1, col + 1];          //  | /
                        v3.Z = (float)raster.Value[row - 1, col];              //  1*
                    }

                    // Test for no-data values and don't calculate hillshade in that case
                    if (v1.Z == noData || v2.Z == noData || v3.Z == noData)
                    {
                        hillshade[row][col] = -1; // should never be negative otherwise.
                        continue;
                    }
                    // Apply the Conversion Factor to put elevation into the same range as lat/lon
                    v1.Z = v1.Z * elevationFactor * extrusion;
                    v2.Z = v2.Z * elevationFactor * extrusion;
                    v3.Z = v3.Z * elevationFactor * extrusion;

                    // Complete the vectors using the latitude/longitude coordinates
                    v1.X = aff[0] + aff[1] * col + aff[2] * row;
                    v1.Y = aff[3] + aff[4] * col + aff[5] * row;

                    v2.X = aff[0] + aff[1] * (col + 1) + aff[2] * (row + 1);
                    v2.Y = aff[3] + aff[4] * (col + 1) + aff[5] * (row + 1);

                    v3.X = aff[0] + aff[1] * col + aff[2] * (row + 1);
                    v3.Y = aff[3] + aff[4] * col + aff[5] * (row + 1);

                    // We need two direction vectors in order to obtain a cross product
                    FloatVector3 dir2 = FloatVector3.Subtract(v2, v1); // points from 1 to 2
                    FloatVector3 dir3 = FloatVector3.Subtract(v3, v1); // points from 1 to 3


                    FloatVector3 cross = FloatVector3.CrossProduct(dir3, dir2); // right hand rule - cross direction should point into page... reflecting more if light direction is in the same direction

                    // Normalizing this vector ensures that this vector is a pure direction and won't affect the intensity
                    cross.Normalize();

                    // Hillshade now has an "intensity" modifier that should be applied to the R, G and B values of the color found at each pixel.
                    hillshade[row][col] = FloatVector3.Dot(cross, lightDirection) * lightIntensity + ambientIntensity;

                }
                pm.CurrentValue = row;
            }
            pm.Reset();
            // Setting this indicates that a hillshade has been created more recently than characteristics have been changed.
            shadedRelief.HasChanged = false;
            return hillshade;
        }
Пример #11
0
 /// <summary>
 /// Creates a CoordinateF by using the X, Y and Z terms of a FloatVector 
 /// </summary>
 /// <param name="floatVector"></param>
 public CoordinateF(FloatVector3 floatVector)
 {
     _x = floatVector.X;
     _y = floatVector.Y;
     _z = floatVector.Z;
     _m = float.NaN;
 }