예제 #1
0
파일: CField.cs 프로젝트: ja003/ForestReco2
        public float?GetAverageHeightFromNeighbourhood(int pKernelSizeMultiplier)
        {
            int pKernelSize = CGroundArray.GetKernelSize();

            pKernelSize *= pKernelSizeMultiplier;

            int   defined   = 0;
            float heightSum = 0;

            for (int x = -pKernelSize; x < pKernelSize; x++)
            {
                for (int y = -pKernelSize; y < pKernelSize; y++)
                {
                    int    xIndex = indexInField.Item1 + x;
                    int    yIndex = indexInField.Item2 + y;
                    CField el     = GetFieldWithOffset(x, y);
                    if (el != null && el.IsDefined())
                    {
                        defined++;
                        heightSum += (float)el.GetHeight();
                    }
                }
            }
            if (defined == 0)
            {
                return(null);
            }
            return(heightSum / defined);
        }
예제 #2
0
파일: CField.cs 프로젝트: ja003/ForestReco2
        /// <summary>
        /// Returns the interpolated height.
        /// Interpolation = bilinear.
        /// </summary>
        public float?GetHeight(Vector3 pPoint)
        {
            if (!HasAllNeighbours() || !HasAllNeighboursDefined(true))
            {
                if (!IsDefined())
                {
                    return(null);
                }
                return(GetHeight());
            }
            //return GetHeight(); //uncomment to cancel interpolation

            //http://www.geocomputation.org/1999/082/gc_082.htm
            //3.4 Bilinear interpolation

            List <CField> bilinearFields = GetBilinearFieldsFor(pPoint);
            CField        h1             = bilinearFields[0];
            CField        h2             = bilinearFields[1];
            CField        h3             = bilinearFields[2];
            CField        h4             = bilinearFields[3];

            float a00 = (float)h1.GetHeight();
            float a10 = (float)h2.GetHeight() - (float)h1.GetHeight();
            float a01 = (float)h3.GetHeight() - (float)h1.GetHeight();
            float a11 = (float)h1.GetHeight() - (float)h2.GetHeight() - (float)h3.GetHeight() + (float)h4.GetHeight();

            float step = CParameterSetter.groundArrayStep;

            float x = pPoint.X - Center.X;

            x += step / 2;
            x  = x / step;
            float y = Center.Y - pPoint.Y;

            y += step / 2;
            y  = y / step;

            if (x < 0 || x > 1 || y < 0 || y > 1)
            {
                CDebug.Error("field " + this + " interpolation is incorrect! x = " + x + " z = " + y);
            }

            //pPoint space coords are X and Z, Y = height
            float hi = a00 + a10 * x + a01 * y + a11 * x * y;

            return(hi);
        }
예제 #3
0
파일: CField.cs 프로젝트: ja003/ForestReco2
        /// <summary>
        /// Sets SmoothHeight based on average from neighbourhood
        /// </summary>
        public void CalculateSmoothHeight(double[,] pGaussKernel)
        {
            if (!IsDefined())
            {
                return;
            }

            //int defined = 0;
            float heightSum = 0;

            float midHeight = (float)GetHeight();

            int kernelSize = CGroundArray.GetKernelSize();

            float gaussWeightSum = 0;

            for (int x = 0; x < kernelSize; x++)
            {
                for (int y = 0; y < kernelSize; y++)
                {
                    int    xIndex   = indexInField.Item1 + x - kernelSize / 2;
                    int    yIndex   = indexInField.Item2 + y - kernelSize / 2;
                    CField el       = CProjectData.Points.groundArray.GetField(xIndex, yIndex);
                    float? elHeight = el?.GetHeight();

                    //if element is not defined, use height from the middle element
                    float definedHeight = midHeight;
                    if (elHeight != null)
                    {
                        definedHeight = (float)elHeight;
                    }
                    float gaussWeight = (float)pGaussKernel[x, y];
                    gaussWeightSum += gaussWeight;
                    heightSum      += definedHeight * gaussWeight;
                }
            }

            SmoothHeight = heightSum;
        }
예제 #4
0
파일: CField.cs 프로젝트: ja003/ForestReco2
        /// <summary>
        /// Finds closest defined fields in direction based on pDiagonal parameter.
        /// Returns average of 2 found heights considering their distance from this field.
        /// </summary>
        public float?GetAverageHeightFromClosestDefined(int pMaxSteps, bool pDiagonal, EHeight pType)
        {
            if (IsDefined())
            {
                return(GetHeight(pType));
            }

            CField closestFirst  = null;
            CField closestSecond = null;
            CField closestLeft   = GetClosestDefined(pDiagonal ? EDirection.LeftTop : EDirection.Left, pMaxSteps);
            CField closestRight  = GetClosestDefined(pDiagonal ? EDirection.RightBot : EDirection.Right, pMaxSteps);
            CField closestTop    = GetClosestDefined(pDiagonal ? EDirection.RightTop : EDirection.Top, pMaxSteps);
            CField closestBot    = GetClosestDefined(pDiagonal ? EDirection.LeftBot : EDirection.Bot, pMaxSteps);

            closestFirst  = closestLeft;
            closestSecond = closestRight;
            if ((closestFirst == null || closestSecond == null) && closestTop != null && closestBot != null)
            {
                closestFirst  = closestTop;
                closestSecond = closestBot;
            }

            if (closestFirst != null && closestSecond != null)
            {
                CField smaller = closestFirst;
                CField higher  = closestSecond;
                if (closestSecond.GetHeight(pType) < closestFirst.GetHeight(pType))
                {
                    higher  = closestFirst;
                    smaller = closestSecond;
                }
                int   totalDistance = smaller.GetStepCountTo(higher);
                float?heightDiff    = higher.GetHeight(pType) - smaller.GetHeight(pType);
                if (heightDiff != null)
                {
                    float?smallerHeight     = smaller.GetHeight();
                    float distanceToSmaller = GetStepCountTo(smaller);

                    return(smallerHeight + distanceToSmaller / totalDistance * heightDiff);
                }
            }
            else if (!HasAllNeighbours())
            {
                if (closestLeft != null)
                {
                    return(closestLeft.GetHeight(pType));
                }
                if (closestTop != null)
                {
                    return(closestTop.GetHeight(pType));
                }
                if (closestRight != null)
                {
                    return(closestRight.GetHeight(pType));
                }
                if (closestBot != null)
                {
                    return(closestBot.GetHeight(pType));
                }
            }
            if (!pDiagonal)
            {
                return(GetAverageHeightFromClosestDefined(pMaxSteps, true, pType));
            }

            return(null);
        }