Example #1
0
        public static void DistanceWithinRectangle(double height, Vector2d rectangleCenterLineStart, Vector2d rectangleCenterLineEnd, double rectangleHalfWitdth, double influenceDistance, List <EPMPoint> pointList, CurveMode curveMode = CurveMode.ReverseLinear, CombineMode combineMode = CombineMode.Add, double limitation = 0)
        {
            Vector2d dir        = rectangleCenterLineEnd - rectangleCenterLineStart;
            double   lineLength = dir.Length();

            dir.Normalize();
            Vector2d normal = new Vector2d(-dir.y, dir.x);

            for (int i = 0; i < pointList.Count; i++)
            {
                EPMPoint p        = pointList[i];
                Vector2d v2       = p.pos2d - rectangleCenterLineStart;
                double   hlength  = v2 * dir;
                double   vlength  = v2 * normal;
                double   distance = 0;
                if (hlength >= 0 && hlength <= lineLength && System.Math.Abs(vlength) <= rectangleHalfWitdth)
                {
                    //The point is in the rectangle
                    distance = EPMGlobal.Min(rectangleHalfWitdth - System.Math.Abs(vlength), hlength, lineLength - hlength);
                    if (distance <= influenceDistance)
                    {
                        double y = GetHeightByCurveMode(distance / influenceDistance, curveMode) * height;
                        SetHeightByCombineMode(p, y, combineMode, limitation);
                    }
                }
                else
                {
                    //The point is outside the rectangle, ignore it.
                    continue;
                }
            }
        }
Example #2
0
        public static void DistanceToLine(double height, Vector2d lineStart, Vector2d lineEnd, double radius, List <EPMPoint> pointList, CurveMode curveMode = CurveMode.ReverseLinear, CombineMode combineMode = CombineMode.Add, double limitation = 0)
        {
            Vector2d dir        = lineEnd - lineStart;
            double   lineLength = dir.Length();

            dir.Normalize();
            Vector2d normal = new Vector2d(-dir.y, dir.x);

            for (int i = 0; i < pointList.Count; i++)
            {
                EPMPoint p        = pointList[i];
                Vector2d v2       = p.pos2d - lineStart;
                double   dot      = v2 * dir;
                double   distance = 0;
                if (dot < 0 || dot > lineLength)
                {
                    //Check the distance to LineStart point and LineEndPoint
                    distance = System.Math.Min(v2.Length(), (p.pos2d - lineEnd).Length());
                }
                else
                {
                    //check the distance to line
                    distance = System.Math.Abs(v2 * normal);
                }

                if (distance < radius)
                {
                    double y = GetHeightByCurveMode(distance / radius, curveMode) * height;
                    SetHeightByCombineMode(p, y, combineMode, limitation);
                }
            }
        }
Example #3
0
 public EPMTriangle(EPMPoint p1, EPMPoint p2, EPMPoint p3)
 {
     g_pointList.Clear();
     g_pointList.Add(p1);
     g_pointList.Add(p2);
     g_pointList.Add(p3);
 }
Example #4
0
        public void GeneratingPoints_Line(int number, EPMPoint.PointType type, Vector2d lineStart, Vector2d lineEnd, double maxDistance, bool uniformly = true)
        {
            Vector2d dir        = lineEnd - lineStart;
            double   lineLength = dir.Length();
            double   uniLength  = lineLength / number;

            dir.Normalize();
            Vector2d normal = new Vector2d(-dir.y, dir.x);

            for (int i = 0; i < number; i++)
            {
                Vector2d v2 = new Vector2d();
                if (uniformly)
                {
                    v2.x = RandomDouble(i * uniLength, (i + 1) * uniLength);
                }
                else
                {
                    v2.x = RandomDouble(0, lineLength);
                }

                v2.y = RandomDouble(-maxDistance, maxDistance);


                v2 = lineStart + v2.x * dir + v2.y * normal;
                if (IsPointInValidRange(v2))
                {
                    EPMPoint p = new EPMPoint(type, new Vector3d(v2.x, 0, v2.y));
                    m_vertexList.Add(p);
                }
            }
        }
Example #5
0
        public static void DistanceToBorderOfRectangle(double height, Vector2d rectangleCenterLineStart, Vector2d rectangleCenterLineEnd, double rectangleHalfWitdth, double influenceDistance, List <EPMPoint> pointList, CurveMode curveMode = CurveMode.ReverseLinear, CombineMode combineMode = CombineMode.Add, double limitation = 0)
        {
            Vector2d dir        = rectangleCenterLineEnd - rectangleCenterLineStart;
            double   lineLength = dir.Length();

            dir.Normalize();
            Vector2d normal = new Vector2d(-dir.y, dir.x);
            Vector2d corner1, corner2, corner3, corner4;

            corner1 = rectangleCenterLineStart + normal * rectangleHalfWitdth;
            corner2 = rectangleCenterLineStart - normal * rectangleHalfWitdth;
            corner3 = rectangleCenterLineEnd + normal * rectangleHalfWitdth;
            corner4 = rectangleCenterLineEnd - normal * rectangleHalfWitdth;

            for (int i = 0; i < pointList.Count; i++)
            {
                EPMPoint p        = pointList[i];
                Vector2d v2       = p.pos2d - rectangleCenterLineStart;
                double   hlength  = v2 * dir;
                double   vlength  = v2 * normal;
                double   distance = 0;
                if (hlength >= 0 && hlength <= lineLength && System.Math.Abs(vlength) <= rectangleHalfWitdth)
                {
                    //The point is in the rectangle, ignore it.
                    continue;
                }
                else
                {
                    if (hlength >= 0 && hlength <= lineLength)
                    {
                        distance = System.Math.Abs(vlength - rectangleHalfWitdth);
                    }
                    else if (System.Math.Abs(vlength) <= rectangleHalfWitdth)
                    {
                        if (hlength > 0)
                        {
                            distance = hlength - lineLength;
                        }
                        else
                        {
                            distance = -hlength;
                        }
                    }
                    else
                    {
                        v2       = p.pos2d;
                        distance = EPMGlobal.Min((v2 - corner1).Length(), (v2 - corner2).Length(), (v2 - corner3).Length(), (v2 - corner4).Length());
                    }

                    if (distance <= influenceDistance)
                    {
                        double y = GetHeightByCurveMode(distance / influenceDistance, curveMode) * height;
                        SetHeightByCombineMode(p, y, combineMode, limitation);
                    }
                }
            }
        }
Example #6
0
        public override void TryDetermineType()
        {
            EPMPoint.PointType t1, t2, t3;
            t1 = g_pointList[0].g_type;
            t2 = g_pointList[1].g_type;
            t3 = g_pointList[2].g_type;

            int sign = EPMPoint.GenerateTypesInt(false, t1, t2, t3);

            //If one of the vertex is ocean point and not all the points are ocean point. It is a oceanside for sure
            if ((sign & (int)EPMPoint.PointType.Ocean) != 0 && (sign - (int)EPMPoint.PointType.Ocean) != 0)
            {
                g_shapeType        = EPMPoint.PointType.OceanSide;
                g_isTypeDetermined = true;
                return;
            }

            int grounds = EPMPoint.GetGroundEnums();

            //If one of the vertice's type is ground, set the tile type to this ground.
            if ((sign & grounds) != 0)
            {
                if ((sign & (int)EPMPoint.PointType.Ground) != 0)
                {
                    g_shapeType = EPMPoint.PointType.Ground;                                                               //Ground has highest priority.
                }
                else if ((sign & (int)EPMPoint.PointType.Sand) != 0)
                {
                    g_shapeType = EPMPoint.PointType.Sand;
                }
                else if ((sign & (int)EPMPoint.PointType.Soil) != 0)
                {
                    g_shapeType = EPMPoint.PointType.Soil;
                }
                else
                {
                    g_shapeType = EPMPoint.PointType.Ground;
                }
                g_isTypeDetermined = true;
            }
            else
            {
                //Find the type that appears 3 times. Set the tile to this type
                if (t1 == t2 && t1 == t3)
                {
                    g_shapeType        = t1;
                    g_isTypeDetermined = true;
                }
                else
                {
                    //Vertices have different types, simply set the tiles type to ground, but leave the determine sign to false, the tile's type depend on its neighbors.
                    g_shapeType        = EPMPoint.PointType.Ground;
                    g_isTypeDetermined = false;
                }
            }
        }
Example #7
0
 public static bool UserDefineSampler(DoubleCallback <EPMPoint> userDefineFunc, List <EPMPoint> pointList, CombineMode mode = CombineMode.Add, double limitation = 0)
 {
     for (int i = 0; i < pointList.Count; i++)
     {
         EPMPoint p = pointList[i];
         double   y = userDefineFunc(p);
         SetHeightByCombineMode(p, y, mode, limitation);
     }
     return(true);
 }
Example #8
0
 public virtual bool HasPoint(EPMPoint p)
 {
     for (int i = 0; i < g_pointList.Count; i++)
     {
         if (g_pointList[i] == p)
         {
             return(true);
         }
     }
     return(false);
 }
Example #9
0
 public bool HasPoint(EPMPoint p)
 {
     for (int i = 0; i < g_pointList.Length; i++)
     {
         if (g_pointList[i] == p)
         {
             return(true);
         }
     }
     return(false);
 }
Example #10
0
 public void GeneratingPoints_Square(int number, EPMPoint.PointType type, Vector2d startPos, Vector2d endPos)
 {
     for (int i = 0; i < number; i++)
     {
         Vector2d v2 = new Vector2d(RandomDouble(startPos.x, endPos.x), RandomDouble(startPos.y, endPos.y));
         if (IsPointInValidRange(v2))
         {
             EPMPoint p = new EPMPoint(type, new Vector3d(v2.x, 0, v2.y));
             m_vertexList.Add(p);
         }
     }
 }
Example #11
0
        private static void SetHeightByCombineMode(EPMPoint point, double height, CombineMode mode, double limitation)
        {
            switch (mode)
            {
            case CombineMode.Add:
                point.g_height += height;
                break;

            case CombineMode.Subtract:
                point.g_height -= height;
                break;

            case CombineMode.Replace:
                point.g_height = height;
                break;

            case CombineMode.ReplaceHighest:
                if (point.g_height <= height)
                {
                    point.g_height = height;
                }
                break;

            case CombineMode.ReplaceLowest:
                if (point.g_height >= height)
                {
                    point.g_height = height;
                }
                break;

            case CombineMode.AddWithLimitation:
                if (point.g_height + height < limitation)
                {
                    point.g_height += height;
                }
                else
                {
                    point.g_height = limitation;
                }
                break;

            case CombineMode.SubtractWithLimitation:
                if (point.g_height - height > limitation)
                {
                    point.g_height -= height;
                }
                else
                {
                    point.g_height = limitation;
                }
                break;
            }
        }
Example #12
0
 public static void DistanceToPoint(double height, Vector2d center, double radius, List <EPMPoint> pointList, CurveMode curveMode = CurveMode.ReverseLinear, CombineMode combineMode = CombineMode.Add, double limitation = 0)
 {
     for (int i = 0; i < pointList.Count; i++)
     {
         EPMPoint p        = pointList[i];
         double   distance = center.Distance(p.pos2d);
         if (distance < radius)
         {
             double y = GetHeightByCurveMode(distance / radius, curveMode) * height;
             SetHeightByCombineMode(p, y, combineMode, limitation);
         }
     }
 }
Example #13
0
 public static void DistanceWithinCircle(double height, Vector2d center, double radius, double influenceDistance, List <EPMPoint> pointList, CurveMode curveMode = CurveMode.ReverseLinear, CombineMode combineMode = CombineMode.Add, double limitation = 0)
 {
     for (int i = 0; i < pointList.Count; i++)
     {
         EPMPoint p        = pointList[i];
         double   distance = radius - center * p.pos2d;
         if (distance >= 0 && distance < influenceDistance)
         {
             double y = GetHeightByCurveMode(distance / influenceDistance, curveMode) * height;
             SetHeightByCombineMode(p, y, combineMode, limitation);
         }
     }
 }
Example #14
0
        public EPMEdge(EPMPoint p1, EPMPoint p2)
        {
            g_startPoint = p1;
            g_endPoint   = p2;
            g_visited    = false;

            if (g_startPoint.g_indexInList < g_endPoint.g_indexInList)
            {
                m_longHash = g_startPoint.g_indexInList + (((long)g_endPoint.g_indexInList) << 31);
            }
            else
            {
                m_longHash = g_endPoint.g_indexInList + (((long)g_startPoint.g_indexInList) << 31);
            }
        }
Example #15
0
        public void GeneratingPoints_Ring(int number, EPMPoint.PointType type, Vector2d center, double minRadius, double maxRadius, bool uniformly = true)
        {
            double uniDegree = System.Math.PI * 2 / number;
            double c1        = (maxRadius - minRadius) / 3 + minRadius;
            double c2        = maxRadius - (maxRadius - minRadius) / 3;

            for (int i = 0; i < number;)
            {
                Vector2d v2 = new Vector2d();
                if (uniformly)
                {
                    double radius = RandomDouble(minRadius, c1);
                    v2.x = System.Math.Cos(uniDegree * i) * radius + center.x;
                    v2.y = System.Math.Sin(uniDegree * i) * radius + center.y;

                    if (IsPointInValidRange(v2))
                    {
                        EPMPoint p = new EPMPoint(type, new Vector3d(v2.x, 0, v2.y));
                        m_vertexList.Add(p);
                    }

                    radius = RandomDouble(c2, maxRadius);
                    v2.x   = System.Math.Cos(uniDegree * (i + 1)) * radius + center.x;
                    v2.y   = System.Math.Sin(uniDegree * (i + 1)) * radius + center.y;

                    if (IsPointInValidRange(v2))
                    {
                        EPMPoint p = new EPMPoint(type, new Vector3d(v2.x, 0, v2.y));
                        m_vertexList.Add(p);
                    }
                    i += 2;
                }
                else
                {
                    double radius = RandomDouble(minRadius, maxRadius);
                    double degree = (double)RandomDouble(0, 2 * System.Math.PI);
                    v2.x = System.Math.Cos(degree) * radius + center.x;
                    v2.y = System.Math.Sin(degree) * radius + center.y;

                    if (IsPointInValidRange(v2))
                    {
                        EPMPoint p = new EPMPoint(type, new Vector3d(v2.x, 0, v2.y));
                        m_vertexList.Add(p);
                    }
                    i++;
                }
            }
        }
Example #16
0
        public void GeneratingBase(int number, EPMPoint.PointType type)
        {
            m_vertexList.Add(new EPMPoint(type, g_startPoint));
            m_vertexList.Add(new EPMPoint(type, new Vector2d(g_endPoint.x, g_startPoint.y)));
            m_vertexList.Add(new EPMPoint(type, g_endPoint));
            m_vertexList.Add(new EPMPoint(type, new Vector2d(g_startPoint.x, g_endPoint.y)));

            for (int i = 0; i < number; i++)
            {
                Vector2d v2 = new Vector2d(RandomDouble(g_startPoint.x, g_endPoint.x), RandomDouble(g_startPoint.y, g_endPoint.y));
                EPMPoint p  = new EPMPoint(type, new Vector3d(v2.x, 0, v2.y));
                m_vertexList.Add(p);
            }

            GeneratingPoints_Line((int)(getXLength() / 5), type, g_startPoint, new Vector2d(g_endPoint.x, g_startPoint.y), 0, true);
            GeneratingPoints_Line((int)(getZlength() / 5), type, new Vector2d(g_endPoint.x, g_startPoint.y), g_endPoint, 0, true);
            GeneratingPoints_Line((int)(getXLength() / 5), type, g_endPoint, new Vector2d(g_startPoint.x, g_endPoint.y), 0, true);
            GeneratingPoints_Line((int)(getZlength() / 5), type, new Vector2d(g_startPoint.x, g_endPoint.y), g_startPoint, 0, true);
        }
Example #17
0
        public void GeneratingPoints_Circle(int number, EPMPoint.PointType type, Vector2d center, double radius)
        {
            double SquaredRadius = radius * radius;

            for (int i = 0; i < number; i++)
            {
                Vector2d v2 = new Vector2d(center.x + RandomDouble(-radius, radius), center.y + RandomDouble(-radius, radius));
                if (v2.SquaredDistance(center) > SquaredRadius)
                {
                    i--;
                }
                else
                {
                    if (IsPointInValidRange(v2))
                    {
                        EPMPoint p = new EPMPoint(type, new Vector3d(v2.x, 0, v2.y));
                        m_vertexList.Add(p);
                    }
                }
            }
        }
Example #18
0
 public EPMLiteTriangle(EPMPoint p1, EPMPoint p2, EPMPoint p3)
 {
     g_pointList[0] = p1;
     g_pointList[1] = p2;
     g_pointList[2] = p3;
 }
Example #19
0
 public bool HasShapeType(EPMPoint.PointType type)
 {
     return(HasShapeType(EPMPoint.GenerateTypesInt(false, type)));
 }
Example #20
0
        //The divideYCount is set by experiment....
        public static List <EPMTriangle> DoDelaunay(List <EPMPoint> pointList, Vector2d regionStart, Vector2d regionEnd, int divideYCount = 12)
        {
            //Shift point's the postion, Treat regionStart as Origin Point;
            if (regionStart.x != 0 || regionStart.y != 0)
            {
                for (int i = 0; i < pointList.Count; i++)
                {
                    pointList[i].pos2d -= regionStart;
                }
            }
            regionEnd -= regionStart;

            //Make a super triangle, All the points are in this super triangle.
            EPMPoint p1, p2, p3;
            double   regionWidth  = regionEnd.x;
            double   regionHeight = regionEnd.y;

            p1 = new EPMPoint(EPMPoint.PointType.Ground, new Vector3d(-regionHeight, 0, -100));
            p2 = new EPMPoint(EPMPoint.PointType.Ground, new Vector3d(regionEnd.x + regionHeight, 0, p1.posZ));
            double tempRatio = regionHeight / (regionHeight + regionWidth / 2);
            double p3y       = (regionHeight + 100f) / tempRatio - 100f;

            p3y += regionHeight;
            p3   = new EPMPoint(EPMPoint.PointType.Ground, new Vector3d((regionEnd.x) / 2, 0, p3y));

            p1.g_indexInList = pointList.Count;
            p2.g_indexInList = p1.g_indexInList + 1;
            p3.g_indexInList = p2.g_indexInList + 1;
            EPMLiteTriangle superTriangle = new EPMLiteTriangle(p1, p2, p3);

            superTriangle.CalculateOuterCircle();


            //triangleList saves the determined triangle.
            List <EPMLiteTriangle> triangleList = new List <EPMLiteTriangle>();

            //tempTriangleList save all the uncertain triangles, put the triangle into different groups according by its outerCircle's coverage on Y-Axis.
            EPMLinkedList <EPMLiteTriangle>[] tempTriangleList = new EPMLinkedList <EPMLiteTriangle> [divideYCount];
            //the pointer to current section of tempTriangleList.
            EPMLinkedList <EPMLiteTriangle> currentSection = null;
            //Use Dictionary to quickly remove duplicate edge. In the test, the edgeDic can at most contains less than 100 edges. But I still can't figure out a way to defeat C#'s dictionary....
            Dictionary <long, EPMEdge> tempEdgeDic = new Dictionary <long, EPMEdge>();

            //Sort the input points by x coordinate.
            pointList.Sort(delegate(EPMPoint comparePoint1, EPMPoint comparePoint2)
            {
                if (comparePoint1.posX > comparePoint2.posX)
                {
                    return(1);
                }
                else if (comparePoint1.posX == comparePoint2.posX)
                {
                    return(0);
                }
                else
                {
                    return(-1);
                }
            });

            //reset the index saved in each point,index is used by edges to generate hash. Hash could accelerate comparation.
            for (int i = 0; i < pointList.Count; i++)
            {
                pointList[i].g_indexInList = i;
            }

            //Put the super triangle into tempList, Super triangle absolutely cover all groups of tempTriangleList.
            for (int i = 0; i < tempTriangleList.Length; i++)
            {
                tempTriangleList[i] = new EPMLinkedList <EPMLiteTriangle>();
                tempTriangleList[i].Push_Back(superTriangle);
            }

            double YSEGMENT = regionHeight / tempTriangleList.Length;


            //Begin Algorithm.
            for (int i = 0; i < pointList.Count; i++)
            {
                tempEdgeDic.Clear();
                EPMPoint cp      = pointList[i];
                int      section = (int)((cp.posZ) / YSEGMENT);
                if (section >= tempTriangleList.Length)
                {
                    section = tempTriangleList.Length - 1;
                }
                currentSection = tempTriangleList[section];
                currentSection.ResetCurrentToHead();
                EPMLiteTriangle ct = currentSection.MoveForward();
                while (ct != null)
                {
                    if (ct.g_visited)
                    {
                        ct = currentSection.DeleteCurrentAndMoveForward();
                        continue;
                    }

                    Vector2d origin = ct.g_outerCircleOrigin;
                    double   radius = ct.g_outerCicleRadius;

                    if (cp.posX - origin.x > radius)
                    {
                        triangleList.Add(ct);
                        ct.g_visited = true;
                        ct           = currentSection.DeleteCurrentAndMoveForward();
                        continue;
                    }
                    else if (cp.pos2d.SquaredDistance(origin) > radius * radius)
                    {
                        ct = currentSection.MoveForward();
                        continue;
                    }
                    else
                    {
                        TryAddEdge(ref tempEdgeDic, new EPMEdge(ct[0], ct[1]));
                        TryAddEdge(ref tempEdgeDic, new EPMEdge(ct[1], ct[2]));
                        TryAddEdge(ref tempEdgeDic, new EPMEdge(ct[2], ct[0]));

                        ct.g_visited = true;
                        ct           = currentSection.DeleteCurrentAndMoveForward();
                    }
                }

                foreach (EPMEdge e in tempEdgeDic.Values)
                {
                    if (e.g_visited)
                    {
                        continue;
                    }
                    EPMLiteTriangle tt = new EPMLiteTriangle(cp, e.g_startPoint, e.g_endPoint);
                    tt.CalculateOuterCircle();

                    int lowerBound = (int)((tt.g_outerCircleOrigin.y - tt.g_outerCicleRadius) / YSEGMENT);
                    if (lowerBound < 0)
                    {
                        lowerBound = 0;
                    }
                    int upperBound = (int)((tt.g_outerCircleOrigin.y + tt.g_outerCicleRadius) / YSEGMENT);
                    if (upperBound >= tempTriangleList.Length)
                    {
                        upperBound = tempTriangleList.Length - 1;
                    }

                    for (int k = lowerBound; k <= upperBound; k++)
                    {
                        tempTriangleList[k].Push_Back(tt);
                    }
                }
            }

            for (int i = 0; i < tempTriangleList.Length; i++)
            {
                currentSection = tempTriangleList[i];
                currentSection.ResetCurrentToHead();
                for (EPMLiteTriangle ct = currentSection.MoveForward(); ct != null; ct = currentSection.MoveForward())
                {
                    if (ct.g_visited == false)
                    {
                        triangleList.Add(ct);
                    }
                }
            }

            List <EPMTriangle> buffer = new List <EPMTriangle>();

            for (int i = triangleList.Count - 1; i >= 0; i--)
            {
                EPMLiteTriangle lt = triangleList[i];
                if (lt.HasPoint(p1) || lt.HasPoint(p2) || lt.HasPoint(p3))
                {
                }
                else
                {
                    buffer.Add(new EPMTriangle(lt[0], lt[1], lt[2]));
                    lt[0].g_neighbors.Add(lt[1]);
                    lt[0].g_neighbors.Add(lt[2]);
                    lt[1].g_neighbors.Add(lt[0]);
                    lt[1].g_neighbors.Add(lt[2]);
                    lt[2].g_neighbors.Add(lt[0]);
                    lt[2].g_neighbors.Add(lt[1]);
                }
            }

            for (int i = 0; i < pointList.Count; i++)
            {
                pointList[i].TidyNeighbors();
            }

            //Shift point's position Back.
            if (regionStart.x != 0 || regionStart.y != 0)
            {
                for (int i = 0; i < pointList.Count; i++)
                {
                    pointList[i].pos2d += regionStart;
                }
            }

            return(buffer);
        }