예제 #1
0
        public bool IntersectsWithLine(LineEquation otherLine, out Vector2 intersectionPoint)
        {
            intersectionPoint = new Vector2(0, 0);

            if (!IsIntersect(new Line()
            {
                p1 = Start, p2 = End
            }, new Line()
            {
                p1 = otherLine.Start, p2 = otherLine.End
            }))
            {
                return(false);
            }

            if (IsVertical && otherLine.IsVertical)
            {
                return(false);
            }
            if (IsVertical || otherLine.IsVertical)
            {
                intersectionPoint = GetIntersectionPointIfOneIsVertical(otherLine, this);
                return(true);
            }
            float delta           = A * otherLine.B - otherLine.A * B;
            bool  hasIntersection = Math.Abs(delta - 0) > 0.0001f;

            if (hasIntersection)
            {
                float x = (otherLine.B * C - B * otherLine.C) / delta;
                float y = (A * otherLine.C - otherLine.A * C) / delta;
                intersectionPoint = new Vector2(x, y);
            }
            return(hasIntersection);
        }
예제 #2
0
 public bool Intersects(LineEquation otherLine)
 {
     return(IsIntersect(new Line()
     {
         p1 = Start, p2 = End
     }, new Line()
     {
         p1 = otherLine.Start, p2 = otherLine.End
     }));
 }
예제 #3
0
        private static Vector2 GetIntersectionPointIfOneIsVertical(LineEquation line1, LineEquation line2)
        {
            LineEquation verticalLine    = line2.IsVertical ? line2 : line1;
            LineEquation nonVerticalLine = line2.IsVertical ? line1 : line2;

            float y = (verticalLine.Start.X - nonVerticalLine.Start.X) *
                      (nonVerticalLine.End.Y - nonVerticalLine.Start.Y) /
                      ((nonVerticalLine.End.X - nonVerticalLine.Start.X)) +
                      nonVerticalLine.Start.Y;
            float x = line1.IsVertical ? line1.Start.X : line2.Start.X;

            return(new Vector2(x, y));
        }
예제 #4
0
        public static List <Polygon> CreateWalls(Polygon polygon, WallData wallData)
        {
            List <List <Vector2> > allPoints = new List <List <Vector2> >();
            List <Vector2>         points    = new List <Vector2>();
            List <Vector2>         lastFace  = new List <Vector2>();
            List <List <Vector2> > normals   = new List <List <Vector2> >();

            PolygonShapeData polyData = polygon.Data as PolygonShapeData;

            List <Vector2> sharedValues = polyData.PolygonPoints.GroupBy(x => x).Where(g => g.Count() > 1).Select(x => x.Key).ToList();

            for (int i = 0; i < polyData.PolygonPoints.Count; i++)
            {
                if (sharedValues.Contains(polyData.PolygonPoints[i]))
                {
                    wallData.facesIndicesToSkip.Add(i);
                    i++;
                }
            }

            for (int i = 0; i < polyData.PolygonPoints.Count; i++)
            {
                if (wallData.facesIndicesToSkip.Contains(i))
                {
                    continue;
                }

                //Okay basically all the shit I'm doing here is getting the vertex normal of the current point
                //and basing how the wall should be made based off that, so all the walls end up as trapazoids.
                //The only exception is if a wall piece is missing, I then get the intersection based on which
                //side of the wall it is, and try to flatten it. It's not perfect but it works?
                int index1 = (i - 1) % polyData.PolygonPoints.Count;
                if (index1 == -1)
                {
                    index1 = polyData.PolygonPoints.Count - 1;
                }
                int     index2 = i % polyData.PolygonPoints.Count;
                int     index3 = (i + 1) % polyData.PolygonPoints.Count;
                int     index4 = (i + 2) % polyData.PolygonPoints.Count;
                Vector2 a      = polyData.PolygonPoints[index1] * polyData.Scalar;
                Vector2 b      = polyData.PolygonPoints[index2] * polyData.Scalar;
                Vector2 c      = polyData.PolygonPoints[index3] * polyData.Scalar;
                Vector2 d      = polyData.PolygonPoints[index4] * polyData.Scalar;

                Vector2 abNormal        = Vector2.Normalize(Shape.GetNormal2D(a, b));
                Vector2 bcNormal        = Vector2.Normalize(Shape.GetNormal2D(b, c));
                Vector2 vertexNormalabc = Vector2.Normalize((abNormal + bcNormal)) * wallData.Thickness;
                Vector2 cdNormal        = Vector2.Normalize(Shape.GetNormal2D(c, d));
                Vector2 vertexNormalbcd = Vector2.Normalize((bcNormal + cdNormal)) * wallData.Thickness;

                Vector2 point  = polyData.PolygonPoints[index2] * polyData.Scalar + vertexNormalabc;
                Vector2 point2 = polyData.PolygonPoints[index3] * polyData.Scalar + vertexNormalbcd;
                points.Add(point);
                points.Add(point2);
                points.Add(c);
                points.Add(b);

                if (wallData.facesIndicesToSkip.Contains(i + 1))
                {
                    LineEquation first  = new LineEquation(points[2], points[2] - bcNormal);
                    LineEquation second = new LineEquation(points[0], points[1]);
                    Vector2      intersectPoint;
                    if (first.IntersectsWithLine(second, out intersectPoint))
                    {
                        points[1] = intersectPoint;
                    }
                }
                if (wallData.facesIndicesToSkip.Contains(i - 1))
                {
                    LineEquation first  = new LineEquation(points[3], points[3] - bcNormal);
                    LineEquation second = new LineEquation(points[0], points[1]);
                    Vector2      intersectPoint;
                    if (first.IntersectsWithLine(second, out intersectPoint))
                    {
                        points[0] = intersectPoint;
                    }
                }

                allPoints.Add(points);
                points = new List <Vector2>();
            }

            //Idk there were edge cases I had NAN values and they didnt seem to affect anything sooooooo
            for (int i = allPoints.Count - 1; i >= 0; i--)
            {
                bool hasNan = false;
                for (int j = 0; j < allPoints[i].Count; j++)
                {
                    if (allPoints[i][j] != allPoints[i][j])
                    {
                        hasNan = true;
                        break;
                    }
                }

                if (hasNan)
                {
                    allPoints.RemoveAt(i);
                }
            }

            VMFDebug.CreateDebugImage("WallOutput", onDraw: (g) =>
            {
                float scale = 0.1f;
                for (int i = 0; i < allPoints.Count; i++)
                {
                    for (int j = 0; j < allPoints[i].Count; j++)
                    {
                        int iN   = (j + 1) % allPoints[i].Count;
                        Point p1 = new Point((int)(allPoints[i][j].X * scale + 100), (int)(allPoints[i][j].Y * scale + 100));
                        Point p2 = new Point((int)(allPoints[i][iN].X * scale + 100), (int)(allPoints[i][iN].Y * scale + 100));

                        g.DrawLine(new Pen(Color.Black, 3), p1, p2);
                    }
                }
            });

            List <Polygon> finalPolygons = new List <Polygon>();

            for (int i = 0; i < allPoints.Count; i++)
            {
                finalPolygons.Add(
                    new Polygon()
                {
                    Position = polygon.Position + new Vector3(0, 0, wallData.Height * 0.5f),
                    Data     = new PolygonShapeData()
                    {
                        Depth         = wallData.Height + ((PolygonShapeData)polygon.Data).Depth,
                        Scalar        = 1,
                        PolygonPoints = allPoints[i]
                    }
                });
            }

            return(finalPolygons);
        }