Exemple #1
0
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                var sides = textBox2.Text;
                if (!string.IsNullOrEmpty(textBox2.Text))
                {
                    var points = sides.Split(new [] { ' ' });

                    var side1 = int.Parse(points[0]);
                    var side2 = int.Parse(points[1]);
                    var side3 = int.Parse(points[2]);

                    triangle = new Triangle(side1, side2, side3);
                    isScaleneLbl.Text = triangle.IsScalene() ? "yes" : "no";
                    isIsolescenesLbl.Text = triangle.IsIsosceles() ? "yes" : "no";
                    isEquilateralLbl.Text = triangle.IsEquilateral() ? "yes" : "no";
                    Refresh();
                }
            }
            catch (FormatException ex)
            {
                MessageBox.Show("Couldn't parse input!");
            }
            catch (ArgumentException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
Exemple #2
0
        public static void Main(string[] args)
        {
            string results = "";
            int x= 0;
            Triangle[]ta = new Triangle[4];

            while( x < 4 )
            {
                ta[x] = new Triangle();
                ta[x].height = (x + 1) * 2;
                ta[x].length = x + 4;
                ta[x].setArea();

                results += "triangle" + x + ", area";
                results += " = " + ta[x].area + "\n";

                x = x + 1;

            }

            int y = x;

            x = 27;

            Triangle t5 = ta[2];
            ta[2].area = 343;
            results += "y = " + y;

            MessageBox.Show(results + ", t5 area = " + t5.area);
        }
Exemple #3
0
        protected void AddVertex(Face face, Vertex vertex)
        {
            base.AddVertex(vertex);
            Faces.Remove(face);

            HalfEdge h1 = face.HalfEdge;
            HalfEdge h2 = h1.Next;
            HalfEdge h3 = h2.Next;

            HalfEdge h4 = new HalfEdge(h1.Origin);
            HalfEdge h5 = new HalfEdge(h2.Origin);
            HalfEdge h6 = new HalfEdge(h3.Origin);
            HalfEdge h7 = new HalfEdge(vertex);
            HalfEdge h8 = new HalfEdge(vertex);
            HalfEdge h9 = new HalfEdge(vertex);
            HalfEdges.AddRange(new List<HalfEdge> {h4, h5, h6, h7, h8, h9});

            h4.Twin = h7;
            h7.Twin = h4;
            h5.Twin = h8;
            h8.Twin = h5;
            h6.Twin = h9;
            h9.Twin = h6;

            // Set all next
            h1.Next = h5;
            h5.Prev = h1;
            h5.Next = h7;
            h7.Prev = h5;
            h7.Next = h1;
            h1.Prev = h7;

            h2.Next = h6;
            h6.Prev = h2;
            h6.Next = h8;
            h8.Prev = h6;
            h8.Next = h2;
            h2.Prev = h8;

            h3.Next = h4;
            h4.Prev = h3;
            h4.Next = h9;
            h9.Prev = h4;
            h9.Next = h3;
            h3.Prev = h9;

            Triangle t1 = new Triangle(h1);
            Triangle t2 = new Triangle(h2);
            Triangle t3 = new Triangle(h3);

            Faces.Add(t1);
            Faces.Add(t2);
            Faces.Add(t3);

            Tree.Add(vertex, t1, t2, t3);

            LogEntry logEntry = new LogEntry("Adding edges.", this);
            logEntry.Objects.Add(vertex);
            Log.Add(logEntry);
        }
Exemple #4
0
        public Mesh Clone()
        {
            Mesh result = new Mesh();
#if COLLIDER_ODE
            result.PBS = PBS;
#endif
            foreach (Vertex v in vertices)
            {
                if (v == null)
                    result.vertices.Add(null);
                else
                    result.vertices.Add(v.Clone());
            }

            foreach (Triangle t in triangles)
            {
                int iV1, iV2, iV3;
                iV1 = vertices.IndexOf(t.v1);
                iV2 = vertices.IndexOf(t.v2);
                iV3 = vertices.IndexOf(t.v3);

                Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]);
                result.Add(newT);
            }

            return result;
        }
        public MeshGrid(int sizeX, int sizeZ, float squareSideSize)
        {
            //this.device = device;
            //basicEffect = new BasicEffect(device);
            this.sizeX = sizeX;
            this.sizeZ = sizeZ;
            this.Vertices = new VertexPositionNormalTexture[sizeX + 1, sizeZ + 1];
            this.Triangles = new Triangle[sizeX*sizeZ*2];
            var rand = new Random();

            int texParam = 2;

            for (int x = 0; x < sizeX+1; x++)
                for (int z = 0; z < sizeZ+1; z++)
                    this.Vertices[x, z] = new VertexPositionNormalTexture(
                        new Vector3(squareSideSize*x, Noise.Generate(x, z)/4, squareSideSize*z),
                        Vector3.Up,
                        new Vector2(texParam * (float)x/(float)SizeX,texParam * (float)z/(float)SizeZ));

            for (int x = 0; x < sizeX; x++)
                for (int z = 0; z < sizeZ; z++)
                {
                    Triangles[x * 2 * sizeZ + z] = new Triangle(x, z, x, z + 1, x + 1, z);
                    Triangles[x * 2 * sizeZ + sizeZ + z] = new Triangle(x, z + 1, x + 1, z, x + 1, z + 1);
                }
        }
Exemple #6
0
 public void badTrianglePointConstructorTest()
 {
     Point pointa = new Point(1, 0);
     Point pointb = new Point(1, 0);
     Point pointc = new Point(3, 5);
     Triangle tria = new Triangle(pointa, pointb, pointc);
 }
        /// <summary>
        /// Checks if a given set of points forms an ear for a given polygon
        /// </summary>
        /// <param name="polygonPoints">The points describing the polygon</param>
        /// <param name="ear">The resulting ear, if applicable</param>
        /// <returns>True if these points form an ear</returns>
        private static bool IsEar(Point2D p1, Point2D p2, Point2D p3, List<Point2D> polygonPoints, out Triangle ear)
        {
            // for now, assign null to the ear
            ear = null;

            // Check if these points form a concave angle
            //if (Point2D.CalculateAngle(p1, p2, p3) > 0)
            //    return false; // Can't be an ear

            // Make a triangle from the given points
            Triangle t = new Triangle(p1, p2, p3);

            // Check all other points of the polygon, if one falls within this triangle, this isn't an ear
            foreach (Point2D p in polygonPoints)
                if (!p.Equals(p1) && !p.Equals(p2) && !p.Equals(p3))
                    if (Triangle.PointInTriangle(t, p))
                        return false;

            // Sort our points counter-clockwise (this is how wpf indices-triangles face 'up')
            t.Points = Point2D.SortPoints(true, p1, p2, p3).ToArray();

            // This is an ear
            ear = t;

            // Remove the center point out of the polygon
            polygonPoints.Remove(p1);

            // Report succes
            return true;
        }
        /// <summary>
        /// Optimized Heightmap, using cells to optimize process of drawing and modifying.
        /// The heightmap is divided into cells which are each surrounded by a bounding box and
        /// hidden if they are outside of the field of view or too far away. The bounding boxes 
        /// are also used to speed up the ray detection test when making modifications to the terrain.
        /// </summary>
        /// <param name="divisions">Size of the map, ex: 256x256</param>
        /// <param name="cellsize">The size of a single quad, ex: 50x50</param>
        /// <param name="cellDivisions">Number of quads in each heightmap cell, ex: 16x16</param>
        public Optimized_Heightmap(GraphicsDevice graphicsDevice, Point divisions, Vector2 cellsize, Point cellDivisions)
        {
            this.size = divisions;
            this.cellSize = cellsize;
            this.cellDivisions = cellDivisions;

            //basicEffect = new BasicEffect(graphicsDevice, null);
            //basicEffect.VertexColorEnabled = true;
            effect = Editor.content.Load<Effect>(@"content\shaders\opt_heightmap");
            effectParams = new EffectParams(ref effect, "TransformWireframe");

            int w = (int)((float)divisions.X / (float)cellDivisions.X);
            int h = (int)((float)divisions.Y / (float)cellDivisions.Y);

            cell = new HeightmapCell[w, h];

            //Build the cells
            for (int y = 0; y < w; y++)
            {
                for (int x = 0; x < h; x++)
                {
                    //get the adjacent cells (max 3) : [0,0],[0,1],[1,0]
                    HeightmapCell[,] adjacent_cell = new HeightmapCell[2, 2];
                    if (x > 0) adjacent_cell[0, 1] = cell[x - 1, y];
                    if (y > 0) adjacent_cell[1, 0] = cell[x, y - 1];
                    if (x > 0 && y > 0) adjacent_cell[0, 0] = cell[x - 1, y - 1];

                    cell[x, y] = new HeightmapCell(graphicsDevice, new Point(x, y), cellDivisions, cellsize, adjacent_cell);
                }
            }

            HeightmapCell.Tri collisionTri = cell[0,0].triangle[0];
            testTri = new Triangle(collisionTri.p1, collisionTri.p2, collisionTri.p3, Color.White);
        }
        public void BasicCase2ShouldReturnBasicTriangles()
        {
            var vol1 = new Mock<IVolume>();
            vol1.SetupAllProperties();
            vol1.Setup(x => x.Height).Returns(1);
            vol1.Setup(x => x.Depth).Returns(1);
            vol1.Setup(x => x.Width).Returns(1);
            vol1.Setup(x => x.GetVoxelValueAt(0, 0, 0)).Returns(FullBlack);
            vol1.Setup(x => x.GetVoxelValueAt(0, 1, 0)).Returns(FullBlack);

            var t1 = new Triangle
            {
                Edge1 = new Point3D { X = 0.5, Y = 0.0, Z = 0.0 },
                Edge2 = new Point3D { X = 0.0, Y = 0.5, Z = 1.0 },
                Edge3 = new Point3D { X = 0.5, Y = 1.0, Z = 0.5 }
            };
            var t2 = new Triangle
            {
                Edge1 = new Point3D { X = 0.5, Y = 0.0, Z = 0.0 },
                Edge2 = new Point3D { X = 0.0, Y = 0.0, Z = 0.5 },
                Edge3 = new Point3D { X = 0.5, Y = 1.0, Z = 0.5 }
            };
            var expected = new List<ITriangle> { t1, t2 };

            Assert.AreEqual(expected, MarchingCubes.Instance.GetTriangles(vol1.Object, Threshold, GridSize));
        }
Exemple #10
0
 public void arrayConstructorTest()
 {
     double[] arraySides;
     arraySides = new double[] { 1.3, 3.5, 2.3 };
     Triangle tria = new Triangle(arraySides);
     Assert.IsTrue(tria.isCorrectTriangle());
 }
Exemple #11
0
 public void isScalenetest()
 {
     Triangle tri = new Triangle(1.0, 2.0, 3.0);
     Assert.IsTrue(tri.isScalene());
     Assert.IsFalse(tri.isIsosceles());
     Assert.IsFalse(tri.isEquilateral());
 }
Exemple #12
0
 public void AssignChildren(Triangle cm, Triangle ct, Triangle cl, Triangle cr)
 {
     childMid = cm;
     childTop = ct;
     childLeft = cl;
     childRight = cr;
 }
Exemple #13
0
        public void BarycentricTest()
        {
            var t = new Triangle(new Vector3F(0, 0, 0), new Vector3F(1, 0, 0), new Vector3F(0, 1, 0));

              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0, 0, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(1, 0, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0, 1, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0, 0.3f, 2)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0.1f, 0.1f, -1)));
              Assert.AreEqual(false, GeometryHelper.IsOver(t, new Vector3F(0, 2, 0)));
              Assert.AreEqual(false, GeometryHelper.IsOver(t, new Vector3F(1, 1, 0)));

              t = new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 1, 0), new Vector3F(0, 0, 1));

              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0, 0, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0, 1, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0, 0, 1)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(2, 0.3f, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(-1, 0.1f, 0.1f)));
              Assert.AreEqual(false, GeometryHelper.IsOver(t, new Vector3F(0, 2, 0)));
              Assert.AreEqual(false, GeometryHelper.IsOver(t, new Vector3F(1, 2, 1)));

              t = new Triangle(new Vector3F(0, 0, 0), new Vector3F(1, 0, 0), new Vector3F(0, 0, 1));

              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0, 0, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(1, 0, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0, 0, 1)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0.3f, 2, 0)));
              Assert.AreEqual(true, GeometryHelper.IsOver(t, new Vector3F(0.1f, -1, 0.1f)));
              Assert.AreEqual(false, GeometryHelper.IsOver(t, new Vector3F(0, 0, 2)));
              Assert.AreEqual(false, GeometryHelper.IsOver(t, new Vector3F(1, 0, 1)));
        }
        static void Main()
        {
            var trianlgle = new Triangle(3, 4, 5);
            Console.WriteLine(trianlgle.CalcTriangleArea(new HeronsFormulaArea()));

            Console.WriteLine(ConvertNumberToString(5));

            Console.WriteLine(FindMaxNumber(5, -1, 3, 2, 14, 2, 3));

            PrintInNumericFormat(1.3, "fixed-point");
            PrintInNumericFormat(0.75, "percentage");
            PrintInNumericFormat(2.30, "leftIndented");

            bool horizontal, vertical;
            Console.WriteLine(CalcPointDistance(3, -1, 3, 2.5));
            Console.WriteLine("Horizontal? " + CheckIfHorizontal(3, -1, 3, 2.5, out horizontal));
            Console.WriteLine("Vertical? " + CheckIfVertical(3, -1, 3, 2.5, out vertical));

            Student peter = new Student("Peter", "Ivanov", "From Sofia, born at 17.03.1992");
            
            Student stella = new Student("Stella", "Markova", "From Vidin, gamer, high results, born at 03.11.1993");
            
            Console.WriteLine("{0} older than {1} -> {2}",
                peter.FirstName, stella.FirstName, peter.IsOlderThan(stella));
        }
Exemple #15
0
 public VoronoiDiagram(MeshFilter mesh, Transform transform)
 {
     _initial = new Triangle(new Pnt(-10000, -10000), new Pnt(10000, -10000), new Pnt(0, 10000));
     _delaunay = new Triangulation(_initial);
     _mesh = mesh;
     _transform = transform;
 }
        public void TestInterpolatedEmissiveWorldTriangle()
        {
            Triangle triangle = new Triangle( new Point( 0.0f, 0.0f, 3.0f ),
                                              new Point( 1.0f, 0.0f, 3.0f ),
                                              new Point( 1.0f, 1.0f, 3.0f ) );

            BarycentricInterpolatedEmissiveMaterial I = new BarycentricInterpolatedEmissiveMaterial( new Color3( 1.0f, 0.0f, 0.0f ),
                                                                                                     new Color3( 0.0f, 1.0f, 0.0f ),
                                                                                                     new Color3( 0.0f, 0.0f, 1.0f ) );

            SimpleObject so = new SimpleObject( triangle, null, new EmissiveMaterialBase[] { I, I }, null, null, null );

            ListScene scene = new ListScene();
            scene.Add( so );

            Framebuffer fb = new Framebuffer( Color3.Black, 500, 500 );

            Cameras.Pinhole( scene, RenderMethod.RecursiveRayTrace,
                             fb, 0, 0.0001f, 0, 1.0f, true,
                             1.0f, 1.0f, 1.0f,
                             new Point( 0.0f, 0.0f, -2.0f ),
                             new Vector( 0.0f, 0.0f, 1.0f ),
                             new Vector( 0.0f, 1.0f, 0.0f ),
                             1, 1, false );

            Assert.IsTrue( Pfm.Compare( fb, 0.01f, 0.02f, "..\\..\\TestImages\\TestInterpolatedEmissiveWorldTriangle.pfm" ) );
        }
        /// <summary>
        /// Individual puzzle. Create a square from 4 triangles.
        /// </summary>
        /// <param name="game">The game object associated with this puzzle.</param>
        /// <param name="player">The player who may complete this puzzle.</param>
        public CreateASquare(Game game, Player player)
            : base(game, player)
        {
            Triangles = new List<Triangle>();
            countUpdates = 0;

            tri1 = new Triangle();
            tri2 = new Triangle();
            tri3 = new Triangle();
            tri4 = new Triangle();

            tri1.Location = new Rectangle(120, 37, 84, 42);
            tri2.Location = new Rectangle(78, 79, 84, 42);
            tri3.Location = new Rectangle(162, 79, 84, 42);
            tri4.Location = new Rectangle(120, 121, 84, 42);

            //Are you proud of me yet?
            tri1.Rot = (randNum = Game1.random.Next(0,2)) == 0 ? Orientation.Up : randNum == 1 ? Orientation.Left : Orientation.Right;
            tri2.Rot = (randNum = Game1.random.Next(0,2)) == 0 ? Orientation.Left : randNum == 1 ? Orientation.Up : Orientation.Down;
            tri3.Rot = (randNum = Game1.random.Next(0,2)) == 0 ? Orientation.Right : randNum == 1 ? Orientation.Up : Orientation.Down;
            tri4.Rot = (randNum = Game1.random.Next(0,2)) == 0 ? Orientation.Down : randNum == 1 ? Orientation.Left : Orientation.Right;

            tri1.Stat = Status.Waiting;
            tri2.Stat = Status.Waiting;
            tri3.Stat = Status.Waiting;
            tri4.Stat = Status.Waiting;

            Triangles.Add(tri1);
            Triangles.Add(tri2);
            Triangles.Add(tri3);
            Triangles.Add(tri4);

            leftClick = new LeftClick(game, player);
        }
Exemple #18
0
        public void Initialize(Microsoft.Xna.Framework.Game game, Color color, IEnumerable<IEnumerable<Vector3>> verticeLists, IEnumerable<IEnumerable<Triangle<byte>>> triangleLists)
        {
            int listCount = verticeLists.Count();
            var vertCount = verticeLists.Sum(l => l.Count());
            var triCount = triangleLists.Sum(l => l.Count());
            var verts = new Vector3[vertCount];
            var tris = new Triangle<uint>[triCount];
            int c = 0;
            int tc = 0;
            for (int i = 0; i < listCount; i++)
            {
                var vertList = verticeLists.ElementAt(i);
                var triList = triangleLists.ElementAt(i);
                var vertOffset = (uint)c;

                foreach (var vert in vertList)
                    verts[c++] = vert;

                foreach (var tri in triList)
                {
                    tris[tc++] = new Triangle<uint>(tri.Type, tri.V0 + vertOffset, tri.V1 + vertOffset, tri.V2 + vertOffset);
                }
            }
            Initialize(game, color, verts, tris);
        }
        public TriangleOver(Triangle t)
        {
            triangles = (float[][])Arrays.CreateJaggedArray(typeof(float), t.GetTriangleCount() * 6 * 3, 2);

            int tcount = 0;
            for (int i = 0; i < t.GetTriangleCount(); i++) {
                float cx = 0;
                float cy = 0;
                for (int p = 0; p < 3; p++) {
                    float[] pt = t.GetTrianglePoint(i, p);
                    cx += pt[0];
                    cy += pt[1];
                }

                cx /= 3;
                cy /= 3;

                for (int p_0 = 0; p_0 < 3; p_0++) {
                    int n = p_0 + 1;
                    if (n > 2) {
                        n = 0;
                    }

                    float[] pt1 = t.GetTrianglePoint(i, p_0);
                    float[] pt2 = t.GetTrianglePoint(i, n);

                    pt1[0] = (pt1[0] + pt2[0]) / 2;
                    pt1[1] = (pt1[1] + pt2[1]) / 2;

                    triangles[(tcount * 3) + 0][0] = cx;
                    triangles[(tcount * 3) + 0][1] = cy;
                    triangles[(tcount * 3) + 1][0] = pt1[0];
                    triangles[(tcount * 3) + 1][1] = pt1[1];
                    triangles[(tcount * 3) + 2][0] = pt2[0];
                    triangles[(tcount * 3) + 2][1] = pt2[1];
                    tcount++;
                }

                for (int p_1 = 0; p_1 < 3; p_1++) {
                    int n_2 = p_1 + 1;
                    if (n_2 > 2) {
                        n_2 = 0;
                    }

                    float[] pt1_3 = t.GetTrianglePoint(i, p_1);
                    float[] pt2_4 = t.GetTrianglePoint(i, n_2);

                    pt2_4[0] = (pt1_3[0] + pt2_4[0]) / 2;
                    pt2_4[1] = (pt1_3[1] + pt2_4[1]) / 2;

                    triangles[(tcount * 3) + 0][0] = cx;
                    triangles[(tcount * 3) + 0][1] = cy;
                    triangles[(tcount * 3) + 1][0] = pt1_3[0];
                    triangles[(tcount * 3) + 1][1] = pt1_3[1];
                    triangles[(tcount * 3) + 2][0] = pt2_4[0];
                    triangles[(tcount * 3) + 2][1] = pt2_4[1];
                    tcount++;
                }
            }
        }
    public static List<List<Vector2>> clip(List<Vector2> boundary, Triangle piece)
    {
        //create Boundary Polygon
        Polygons boundaryPoly = createPolygons(boundary);

        //create Polygon from the triangular piece
        Polygons subjPoly = createPolygons(piece);

        //clip triangular polygon against the boundary polygon
        Polygons result = new Polygons();
        Clipper c = new Clipper();
        c.AddPaths(subjPoly, PolyType.ptClip, true);
        c.AddPaths(boundaryPoly, PolyType.ptSubject, true);
        c.Execute(ClipType.ctIntersection, result, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);

        List<List<Vector2>> clippedPolygons = new List<List<Vector2>>();

        foreach (Polygon poly in result)
        {
            List<Vector2> clippedPoly = new List<Vector2>();
            foreach (IntPoint p in poly)
            {
                clippedPoly.Add(new Vector2(p.X, p.Y) / multiplier);
            }
            clippedPolygons.Add(clippedPoly);

        }
        return clippedPolygons;
        
    }
Exemple #21
0
        public void CoplanarAndDegenerate()
        {
            var tA = new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 0, 10), new Vector3F(0, 0, 10));
              var tB = new Triangle(new Vector3F(-10, 0, 10), new Vector3F(-10, 0, 20), new Vector3F(10, 0, 20));

              for (int i = 0; i < 2; i++)
              {
            for (int j = 0; j < 3; j++)
            {
              for (int k = 0; k < 3; k++)
              {
            Vector3F p, n;
            float d;
            bool haveContact = TriangleTriangleAlgorithm.GetContact(ref tA, ref tB, out p, out n, out d);

            Assert.AreEqual(false, haveContact);

            // "Rotate" triangle to test next edges.
            var oldB = tB;
            tB[0] = oldB[1];
            tB[1] = oldB[2];
            tB[2] = oldB[0];
              }

              // "Rotate" triangle to test next edges.
              var oldA = tA;
              tA[0] = oldA[1];
              tA[1] = oldA[2];
              tA[2] = oldA[0];
            }

            MathHelper.Swap(ref tA, ref tB);
              }
        }
        // Button Methods
        private void btnCalculate_Click(object sender, EventArgs e)
        {
            double length;

            // TryParse method must be evaluated first so it can set the length variable
            if (Double.TryParse(txtLength.Text, out length) && length > 0)
            {
                RegularPolygon selectedPolygon;

                // Select child class based on what radio button the user has selected
                if (rbTriangle.Checked)
                {
                    selectedPolygon = new Triangle(length);
                }
                else if (rbSquare.Checked)
                {
                    selectedPolygon = new Square(length);
                }
                else
                {
                    selectedPolygon = new Pentagon(length);
                }

                // Calculate and display the perimeter and area of the regular polygon
                lblCalculatedPerimeter.Text = String.Format("{0}", selectedPolygon.CalculatePerimeter());
                lblCalculatedArea.Text = String.Format("{0}", selectedPolygon.CalculateArea());
            }
            else
            {
                MessageBox.Show("You have entered an invaild length.\nPlease enter a positive numeric value and try agian.", "Invalid Length", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                ClearAllFields();
            }
        }
Exemple #23
0
        public void SetSize(float left, float right, float bottom, float top)
        {
            var tris = new Triangle<VertexTP2>[2];
            var p1 = new Vector2(left , bottom);
            var p2 = new Vector2(right, bottom);
            var p3 = new Vector2(right, top);
            var p4 = new Vector2(left, top);
            var t1 = new Vector2(0f, 0f);
            var t2 = new Vector2(1f, 0f);
            var t3 = new Vector2(1f, 1f);
            var t4 = new Vector2(0f, 1f);

            tris[0].A.Position = p1;
            tris[0].A.TexCoord = t1;
            tris[0].B.Position = p2;
            tris[0].B.TexCoord = t2;
            tris[0].C.Position = p3;
            tris[0].C.TexCoord = t3;
            tris[1].A.Position = p3;
            tris[1].A.TexCoord = t3;
            tris[1].B.Position = p4;
            tris[1].B.TexCoord = t4;
            tris[1].C.Position = p1;
            tris[1].C.TexCoord = t1;

            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            var sizeInBytes = Marshal.SizeOf(new Triangle<VertexTP2>());
            GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeInBytes * 2), tris, BufferUsageHint.StaticDraw);
        }
 public static void Main()
 {
     Triangle triangle = new Triangle(3, 4, 5);
     AreaCalculator areaCalculator = new AreaCalculator(triangle);
     double triangleArea = areaCalculator.CalcArea();
     Console.WriteLine(triangleArea);
 }
Exemple #25
0
 public void isScaleneTest()
 {
     Triangle tritest = new Triangle(3.0, 4.0, 5.0);
     Assert.IsTrue(tritest.isScalene());
     Assert.IsFalse(tritest.isIsosceles());
     Assert.IsFalse(tritest.isEquilateral());
 }
    static void Main()
    {
        var shapes = new Shape[numberOfShapes];

        for (int i = 0; i < shapes.Length; i++)
        {
            switch (vladoRandoma.Next() % 3)
            {
                case 0:
                    shapes[i] = new Triangle(widths[vladoRandoma.Next(0, widths.Length)],
                                                 heights[vladoRandoma.Next(0, heights.Length)]);
                    break;
                case 1: shapes[i] = new Rectangle(widths[vladoRandoma.Next(0, widths.Length)],
                                                 heights[vladoRandoma.Next(0, heights.Length)]);
                    break;
                case 2: shapes[i] = new Circle(heights[vladoRandoma.Next(0, heights.Length)]);
                    break;

                default:
                    break;
            }
        }

        foreach (var item in shapes)
        {
            Console.WriteLine(item.ToString().Replace(',', '.'));
        }
    }
Exemple #27
0
        static void Main(string[] args)
        {
            List<String> triangles = new List<String>();

            try {
                FileStream file = new FileStream("triangles.txt", FileMode.Open);
                StreamReader stream = new StreamReader(file);

                while(!stream.EndOfStream) {
                    triangles.Add(stream.ReadLine());
                }

                stream.Close();
                file.Close();
            }
            catch(Exception e) {
                Console.WriteLine(e);
            }

            int count = 0;
            for (int i = 0; i < triangles.Count; i++) {
                bool result = new Triangle(triangles[i]).Score();
                if(result) {
                    count++;
                }
            }

            Console.WriteLine(count);
            Console.ReadLine();
        }
    /*1.	Define abstract class Shape with only one abstract method CalculateSurface() and fields width and height.
        * Define two new classes Triangle and Rectangle that implement the virtual method and
        * return the surface of the figure (height*width for rectangle and height*width/2 for triangle).
        * Define class Circle and suitable constructor so that
        * on initialization height must be kept equal to width and implement the CalculateSurface() method.
        * Write a program that tests the behavior of  the CalculateSurface() method for different shapes (Circle, Rectangle, Triangle) stored in an array.*/
    static void Main()
    {
        Shape rectangle = new Rectangle(4.0, 5.5);
        Console.WriteLine("Surface of rectangle is: {0}", rectangle.CalculateSurface());

        Shape triangle = new Triangle(4.0, 5.5);
        Console.WriteLine("Surface of triangle is: {0}", triangle.CalculateSurface());

        Shape circle = new Circle(4.5);
        Console.WriteLine("Surface of circle is: {0:F6}", circle.CalculateSurface());

        Console.WriteLine();
        Console.WriteLine("---different shapes---");
        Shape[] shapes = {rectangle,
                            triangle,
                            circle,
                            new Circle(6.3),
                            new Triangle(4.6, 7.3)
                };

        foreach (var shape in shapes)
        {
            Console.WriteLine("Surface of {0} is {1}", shape.GetType(), shape.CalculateSurface());
        }
    }
Exemple #29
0
        public void ExpectArgumentExceptionWhenCreateInvalidTriangle()
        {
            var validExceptionsCount = 3;
            var exceptionCount = 0;
            var sideCases = new List<Sides>
            {
                new Sides(1.0, 2.0, 5.0),
                new Sides(-2.0, 4.0, 5.0),
                new Sides(0, 1.0, 2.0)
            };

            foreach (var side in sideCases)
            {
                try
                {
                    var triangle = new Triangle(side.A, side.B, side.C);
                }
                catch (ArgumentException)
                {
                    exceptionCount++;
                }
                catch (Exception ex)
                {
                    Assert.Fail("Возникло не ожидаемое исключение. Детали: {0}", ex.Message);
                }
            }

            Assert.AreEqual(validExceptionsCount, exceptionCount);
        }
Exemple #30
0
 public void PlotTriple(Site s1, Site s2, Site s3) {
     if (Debug) {
         Console.WriteLine("triple {0} {1} {2}", s1, s2, s3);
     }
     var triangle = new Triangle(s1, s2, s3) { New = true };
     Triangles.Add(triangle);
 }
Exemple #31
0
 protected void DrawTriangle(TextureGL texture, Triangle vertexTriangle, ColourInfo drawColour, RectangleF?textureRect = null, Action <TexturedVertex2D> vertexAction = null,
                             Vector2?inflationPercentage = null)
 => texture.DrawTriangle(vertexTriangle, drawColour, textureRect, vertexAction, inflationPercentage);
Exemple #32
0
        public static void CollDetectSphereStaticMeshOverlap(BoundingSphere oldSphere, BoundingSphere newSphere,
                                                             TriangleMesh mesh, CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            float sphereTolR  = collTolerance + newSphere.Radius;
            float sphereTolR2 = sphereTolR * sphereTolR;

            unsafe
            {
#if USE_STACKALLOC
                SmallCollPointInfo *collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
                int *potentialTriangles     = stackalloc int[MaxLocalStackTris];
                {
                    {
#else
                SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                fixed(SmallCollPointInfo *collPts = collPtArray)
                {
                    int[] potTriArray = IntStackAlloc();
                    fixed(int *potentialTriangles = potTriArray)
                    {
#endif
                        int numCollPts = 0;

                        Vector3 collNormal = Vector3.Zero;

                        BoundingBox bb = BoundingBoxHelper.InitialBox;
                        BoundingBoxHelper.AddSphere(newSphere, ref bb);
                        int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                        // Deano : get the spheres centers in triangle mesh space
                        Vector3 newSphereCen = Vector3.Transform(newSphere.Center, mesh.InverseTransformMatrix);
                        Vector3 oldSphereCen = Vector3.Transform(oldSphere.Center, mesh.InverseTransformMatrix);

                        for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                        {
                            IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);
                            float           distToCentre = meshTriangle.Plane.DotCoordinate(newSphereCen);

                            if (distToCentre <= 0.0f)
                            {
                                continue;
                            }
                            if (distToCentre >= sphereTolR)
                            {
                                continue;
                            }
                            int i0, i1, i2;
                            meshTriangle.GetVertexIndices(out i0, out i1, out i2);

                            Triangle triangle = new Triangle(mesh.GetVertex(i0), mesh.GetVertex(i1), mesh.GetVertex(i2));

                            float s, t;
                            float newD2 = Distance.PointTriangleDistanceSq(out s, out t, newSphereCen, triangle);

                            if (newD2 < sphereTolR2)
                            {
                                // have overlap - but actually report the old intersection
                                float oldD2 = Distance.PointTriangleDistanceSq(out s, out t, oldSphereCen, triangle);
                                float dist  = (float)System.Math.Sqrt((float)oldD2);
                                float depth = oldSphere.Radius - dist;

                                Vector3 triPointSTNorm = oldSphereCen - triangle.GetPoint(s, t);
                                JiggleMath.NormalizeSafe(ref triPointSTNorm);

                                Vector3 collisionN = (dist > float.Epsilon) ? triPointSTNorm : triangle.Normal;

                                // since impulse get applied at the old position
                                Vector3 pt = oldSphere.Center - oldSphere.Radius * collisionN;

                                if (numCollPts < MaxLocalStackSCPI)
                                {
                                    collPts[numCollPts++] = new SmallCollPointInfo(pt - body0Pos, pt - body1Pos, depth);
                                }
                                collNormal += collisionN;
                            }
                        }

                        if (numCollPts > 0)
                        {
                            JiggleMath.NormalizeSafe(ref collNormal);
                            collisionFunctor.CollisionNotify(ref info, ref collNormal, collPts, numCollPts);
                        }
#if USE_STACKALLOC
                    }
                }
#else
                        FreeStackAlloc(potTriArray);
                    }
                    FreeStackAlloc(collPtArray);
                }
#endif
            }
        }
Exemple #33
0
        /// <summary>
        /// GetBoxTriangleIntersectionPoints
        /// Pushes intersection points onto the back of pts. Returns the
        /// number of points found.
        /// Points that are close together (compared to
        /// combinationDistance) get combined
        /// </summary>
        /// <param name="pts"></param>
        /// <param name="box"></param>
        /// <param name="triangle"></param>
        /// <param name="combinationDistance"></param>
        /// <returns>int</returns>
        private static int GetBoxTriangleIntersectionPoints(List <Vector3> pts, Box box, Triangle triangle, float combinationDistance)
        {
            // first intersect each edge of the box with the triangle
            Box.Edge[] edges;
            box.GetEdges(out edges);
            Vector3[] boxPts;
            box.GetCornerPoints(out boxPts);

            float tS;
            float tv1, tv2;

            // BEN-OPTIMISATION: Allocating just one Vector3 to be reused.
            Vector3 point = new Vector3();

            int iEdge;

            for (iEdge = 0; iEdge < 12; ++iEdge)
            {
                Box.Edge edge = edges[iEdge];
                Segment  seg  = new Segment(boxPts[(int)edge.Ind0], boxPts[(int)edge.Ind1] - boxPts[(int)edge.Ind0]);
                if (Intersection.SegmentTriangleIntersection(out tS, out tv1, out tv2, seg, triangle))
                {
                    // BEN-OPTIMISATION: Reusing the existing point variable instead allocating new ones.
                    //                   This also allows point to be based by reference.
                    seg.GetPoint(ref point, tS);
                    AddPoint(pts, ref point, combinationDistance * combinationDistance);
                }
            }

            Vector3 pos, n;

            // now each edge of the triangle with the box
            for (iEdge = 0; iEdge < 3; ++iEdge)
            {
                #region "BEN-OPTIMISATION: Remove excess allocations and pass variables by reference."
                // ORIGINAL CODE:

                /*Vector3 pt0 = triangle.GetPoint(iEdge);
                 * Vector3 pt1 = triangle.GetPoint((iEdge + 1) % 3);
                 * Segment s1 = new Segment(pt0, pt1 - pt0);
                 * Segment s2 = new Segment(pt1, pt0 - pt1);*/

                // OPTIMISED CODE:
                Vector3 pt0 = triangle.GetPoint(iEdge);
                Vector3 pt1 = triangle.GetPoint((iEdge + 1) % 3);

                Vector3 difference1;
                Vector3 difference2;

                Vector3.Subtract(ref pt1, ref pt0, out difference1);
                Vector3.Subtract(ref pt0, ref pt1, out difference2);

                Segment s1 = new Segment(ref pt0, ref difference1);
                Segment s2 = new Segment(ref pt1, ref difference2);
                #endregion

                if (box.SegmentIntersect(out tS, out pos, out n, s1))
                {
                    AddPoint(pts, ref pos, combinationDistance * combinationDistance);
                }
                if (box.SegmentIntersect(out tS, out pos, out n, s2))
                {
                    AddPoint(pts, ref pos, combinationDistance * combinationDistance);
                }
            }

            return(pts.Count);
        }
Exemple #34
0
 public bool Equals(Triangle obj)
 {
     return(obj.A.Equals(A) && obj.B.Equals(B) && obj.C.Equals(C));
 }
Exemple #35
0
 public TrigEnumerator(Triangle triangle)
 {
     this.t = triangle;
 }
Exemple #36
0
 /// <summary>
 /// Draws a triangle to the screen.
 /// </summary>
 /// <param name="vertexTriangle">The triangle to draw.</param>
 /// <param name="drawColour">The vertex colour.</param>
 /// <param name="textureRect">The texture rectangle.</param>
 /// <param name="vertexAction">An action that adds vertices to a <see cref="VertexBatch{T}"/>.</param>
 /// <param name="inflationPercentage">The percentage amount that <paramref name="textureRect"/> should be inflated.</param>
 internal abstract void DrawTriangle(Triangle vertexTriangle, ColourInfo drawColour, RectangleF?textureRect = null, Action <TexturedVertex2D> vertexAction = null,
                                     Vector2?inflationPercentage = null);
Exemple #37
0
    public Tuple <IEnumerable <Triangle>, IEnumerable <Triangle> > Split(Plane plane)
    {
        float[] distance = new float[] {
            plane.GetDistanceToPoint(this.V1),
            plane.GetDistanceToPoint(this.V2),
            plane.GetDistanceToPoint(this.V3)
        };

        int onPlane    = distance.Count(d => Mathf.Abs(d) <= smallDistance);
        int abovePlane = distance.Count(d => Mathf.Abs(d) > smallDistance && d > 0);
        int belowPlane = distance.Count(d => Mathf.Abs(d) > smallDistance && d < 0);

        if (belowPlane == 0)
        {
            return(new Tuple <IEnumerable <Triangle>, IEnumerable <Triangle> >(this.Yield(), Enumerable.Empty <Triangle>()));
        }
        if (abovePlane == 0)
        {
            return(new Tuple <IEnumerable <Triangle>, IEnumerable <Triangle> >(Enumerable.Empty <Triangle>(), this.Yield()));
        }
        if (onPlane == 0)
        {
            var single  = abovePlane == 1 ? this.ToEnumerable().First(v => plane.GetDistanceToPoint(v) > 0) : this.ToEnumerable().First(v => plane.GetDistanceToPoint(v) < 0);
            var double1 = abovePlane == 1 ? this.ToEnumerable().First(v => plane.GetDistanceToPoint(v) < 0) : this.ToEnumerable().First(v => plane.GetDistanceToPoint(v) > 0);
            var double2 = abovePlane == 1 ? this.ToEnumerable().Where(v => plane.GetDistanceToPoint(v) < 0).Skip(1).First() : this.ToEnumerable().Where(v => plane.GetDistanceToPoint(v) > 0).Skip(1).First();

            var intersect1 = Math3d.LinePlaneIntersection(plane, single, double1);
            var intersect2 = Math3d.LinePlaneIntersection(plane, single, double2);

            if (abovePlane == 1)
            {
                return(new Tuple <IEnumerable <Triangle>, IEnumerable <Triangle> >(
                           Triangle.TryCreateEnum(single, intersect1, intersect2),
                           Triangle.TryCreateEnum(double1, double2, intersect1)
                           .Concat(Triangle.TryCreateEnum(double2, intersect1, intersect2))));
            }
            else
            {
                return(new Tuple <IEnumerable <Triangle>, IEnumerable <Triangle> >(
                           Triangle.TryCreateEnum(double1, double2, intersect1)
                           .Concat(Triangle.TryCreateEnum(double2, intersect1, intersect2)),
                           Triangle.TryCreateEnum(single, intersect1, intersect2)));
            }
        }
        if (onPlane == 1)
        {
            var   vertexOn    = this.ToEnumerable().First(v => Mathf.Abs(plane.GetDistanceToPoint(v)) <= smallDistance);
            var   vertexBelow = this.ToEnumerable().First(v => plane.GetDistanceToPoint(v) < 0 && Mathf.Abs(plane.GetDistanceToPoint(v)) > smallDistance);
            var   vertexAbove = this.ToEnumerable().First(v => plane.GetDistanceToPoint(v) > 0 && Mathf.Abs(plane.GetDistanceToPoint(v)) > smallDistance);
            var   ray         = new Ray(vertexAbove, vertexBelow - vertexAbove);
            float dst;
            plane.Raycast(ray, out dst);
            var intersect = ray.GetPoint(dst);

            return(new Tuple <IEnumerable <Triangle>, IEnumerable <Triangle> >(Triangle.TryCreateEnum(vertexBelow, vertexOn, intersect), Triangle.TryCreateEnum(vertexAbove, vertexOn, intersect)));
        }
        return(new Tuple <IEnumerable <Triangle>, IEnumerable <Triangle> >(Enumerable.Empty <Triangle>(), Enumerable.Empty <Triangle>()));
    }
Exemple #38
0
        /// <summary>
        /// Find the holes and infect them. Find the area constraints and infect
        /// them. Infect the convex hull. Spread the infection and kill triangles.
        /// Spread the area constraints.
        /// </summary>
        public void CarveHoles()
        {
            Otri         searchtri = default(Otri);
            Vertex       searchorg, searchdest;
            LocateResult intersect;

            Triangle[] regionTris = null;

            if (!mesh.behavior.Convex)
            {
                // Mark as infected any unprotected triangles on the boundary.
                // This is one way by which concavities are created.
                InfectHull();
            }

            if (!mesh.behavior.NoHoles)
            {
                // Infect each triangle in which a hole lies.
                foreach (var hole in mesh.holes)
                {
                    // Ignore holes that aren't within the bounds of the mesh.
                    if (mesh.bounds.Contains(hole))
                    {
                        // Start searching from some triangle on the outer boundary.
                        searchtri.triangle = Mesh.dummytri;
                        searchtri.orient   = 0;
                        searchtri.SymSelf();
                        // Ensure that the hole is to the left of this boundary edge;
                        // otherwise, locate() will falsely report that the hole
                        // falls within the starting triangle.
                        searchorg  = searchtri.Org();
                        searchdest = searchtri.Dest();
                        if (Primitives.CounterClockwise(searchorg, searchdest, hole) > 0.0)
                        {
                            // Find a triangle that contains the hole.
                            intersect = mesh.locator.Locate(hole, ref searchtri);
                            if ((intersect != LocateResult.Outside) && (!searchtri.IsInfected()))
                            {
                                // Infect the triangle. This is done by marking the triangle
                                // as infected and including the triangle in the virus pool.
                                searchtri.Infect();
                                viri.Add(searchtri.triangle);
                            }
                        }
                    }
                }
            }

            // Now, we have to find all the regions BEFORE we carve the holes, because locate() won't
            // work when the triangulation is no longer convex. (Incidentally, this is the reason why
            // regional attributes and area constraints can't be used when refining a preexisting mesh,
            // which might not be convex; they can only be used with a freshly triangulated PSLG.)
            if (mesh.regions.Count > 0)
            {
                int i = 0;

                regionTris = new Triangle[mesh.regions.Count];

                // Find the starting triangle for each region.
                foreach (var region in mesh.regions)
                {
                    regionTris[i] = Mesh.dummytri;
                    // Ignore region points that aren't within the bounds of the mesh.
                    if (mesh.bounds.Contains(region.point))
                    {
                        // Start searching from some triangle on the outer boundary.
                        searchtri.triangle = Mesh.dummytri;
                        searchtri.orient   = 0;
                        searchtri.SymSelf();
                        // Ensure that the region point is to the left of this boundary
                        // edge; otherwise, locate() will falsely report that the
                        // region point falls within the starting triangle.
                        searchorg  = searchtri.Org();
                        searchdest = searchtri.Dest();
                        if (Primitives.CounterClockwise(searchorg, searchdest, region.point) > 0.0)
                        {
                            // Find a triangle that contains the region point.
                            intersect = mesh.locator.Locate(region.point, ref searchtri);
                            if ((intersect != LocateResult.Outside) && (!searchtri.IsInfected()))
                            {
                                // Record the triangle for processing after the
                                // holes have been carved.
                                regionTris[i]        = searchtri.triangle;
                                regionTris[i].region = region.id;
                            }
                        }
                    }

                    i++;
                }
            }

            if (viri.Count > 0)
            {
                // Carve the holes and concavities.
                Plague();
            }

            if (regionTris != null)
            {
                var iterator = new RegionIterator(mesh);

                for (int i = 0; i < regionTris.Length; i++)
                {
                    if (regionTris[i] != Mesh.dummytri)
                    {
                        // Make sure the triangle under consideration still exists.
                        // It may have been eaten by the virus.
                        if (!Otri.IsDead(regionTris[i]))
                        {
                            // Apply one region's attribute and/or area constraint.
                            iterator.Process(regionTris[i]);
                        }
                    }
                }
            }

            // Free up memory (virus pool should be empty anyway).
            viri.Clear();
        }
Exemple #39
0
 /// <summary>
 /// Set the region attribute of all trianlges connected to given triangle.
 /// </summary>
 public void Process(Triangle triangle)
 {
     // Default action is to just set the region id for all trianlges.
     this.Process(triangle, (tri) => { tri.region = triangle.region; });
 }
Exemple #40
0
        internal static void CollDetectSphereStaticMeshSweep(BoundingSphere oldSphere, BoundingSphere newSphere, TriangleMesh mesh,
                                                             CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            // really use a swept test - or overlap?
            Vector3 delta = newSphere.Center - oldSphere.Center;

            if (delta.LengthSquared() < (0.25f * newSphere.Radius * newSphere.Radius))
            {
                CollDetectSphereStaticMeshOverlap(oldSphere, newSphere, mesh, info, collTolerance, collisionFunctor);
            }
            else
            {
                Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
                Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

                float sphereTolR = collTolerance + oldSphere.Radius;
                float sphereToR2 = sphereTolR * sphereTolR;

                Vector3 collNormal = Vector3.Zero;

                BoundingBox bb = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddSphere(oldSphere, ref bb);
                BoundingBoxHelper.AddSphere(newSphere, ref bb);

                // get the spheres centers in triangle mesh space
                Vector3 newSphereCen = Vector3.Transform(newSphere.Center, mesh.InverseTransformMatrix);
                Vector3 oldSphereCen = Vector3.Transform(oldSphere.Center, mesh.InverseTransformMatrix);

                unsafe
                {
#if USE_STACKALLOC
                    SmallCollPointInfo *collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
                    int *potentialTriangles     = stackalloc int[MaxLocalStackTris];
                    {
                        {
#else
                    SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                    fixed(SmallCollPointInfo *collPts = collPtArray)
                    {
                        int[] potTriArray = IntStackAlloc();
                        fixed(int *potentialTriangles = potTriArray)
                        {
#endif
                            int numCollPts = 0;

                            int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                            for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                            {
                                // first test the old sphere for being on the wrong side
                                IndexedTriangle meshTriangle    = mesh.GetTriangle(potentialTriangles[iTriangle]);
                                float           distToCentreOld = meshTriangle.Plane.DotCoordinate(oldSphereCen);
                                if (distToCentreOld <= 0.0f)
                                {
                                    continue;
                                }
                                // now test the new sphere for being clear

                                float distToCentreNew = meshTriangle.Plane.DotCoordinate(newSphereCen);
                                if (distToCentreNew > sphereTolR)
                                {
                                    continue;
                                }

                                int i0, i1, i2;
                                meshTriangle.GetVertexIndices(out i0, out i1, out i2);

                                Triangle triangle = new Triangle(mesh.GetVertex(i0), mesh.GetVertex(i1), mesh.GetVertex(i2));

                                // If the old sphere is intersecting, just use that result
                                float s, t;
                                float d2 = Distance.PointTriangleDistanceSq(out s, out t, oldSphereCen, triangle);

                                if (d2 < sphereToR2)
                                {
                                    float   dist      = (float)System.Math.Sqrt(d2);
                                    float   depth     = oldSphere.Radius - dist;
                                    Vector3 triangleN = triangle.Normal;
                                    Vector3 normSafe  = oldSphereCen - triangle.GetPoint(s, t);

                                    JiggleMath.NormalizeSafe(ref normSafe);

                                    Vector3 collisionN = (dist > float.Epsilon) ? normSafe : triangleN;
                                    // since impulse gets applied at the old position
                                    Vector3 pt = oldSphere.Center - oldSphere.Radius * collisionN;
                                    if (numCollPts < MaxLocalStackSCPI)
                                    {
                                        collPts[numCollPts++] = new SmallCollPointInfo(pt - body0Pos, pt - body1Pos, depth);
                                    }
                                    collNormal += collisionN;
                                }
                                else if (distToCentreNew < distToCentreOld)
                                {
                                    // old sphere is not intersecting - do a sweep, but only if the sphere is moving into the
                                    // triangle
                                    Vector3 pt, N; // CHECK THIS
                                    float   depth;
                                    if (Intersection.SweptSphereTriangleIntersection(out pt, out N, out depth, oldSphere, newSphere, triangle,
                                                                                     distToCentreOld, distToCentreNew, Intersection.EdgesToTest.EdgeAll, Intersection.CornersToTest.CornerAll))
                                    {
                                        // collision point etc must be relative to the old position because that's
                                        //where the impulses are applied
                                        float   dist      = (float)System.Math.Sqrt(d2);
                                        float   depth2    = oldSphere.Radius - dist;
                                        Vector3 triangleN = triangle.Normal;
                                        Vector3 normSafe  = oldSphereCen - triangle.GetPoint(s, t);
                                        JiggleMath.NormalizeSafe(ref normSafe);
                                        Vector3 collisionN = (dist > JiggleMath.Epsilon) ? normSafe : triangleN;
                                        // since impulse gets applied at the old position
                                        Vector3 pt2 = oldSphere.Center - oldSphere.Radius * collisionN;
                                        if (numCollPts < MaxLocalStackSCPI)
                                        {
                                            collPts[numCollPts++] = new SmallCollPointInfo(pt2 - body0Pos, pt2 - body1Pos, depth);
                                        }
                                        collNormal += collisionN;
                                    }
                                }
                            }
                            if (numCollPts > 0)
                            {
                                JiggleMath.NormalizeSafe(ref collNormal);
                                collisionFunctor.CollisionNotify(ref info, ref collNormal, collPts, numCollPts);
                            }
                        }

#if USE_STACKALLOC
                    }
                }
#else
                        FreeStackAlloc(potTriArray);
                    }
                    FreeStackAlloc(collPtArray);
                }
#endif
            }
        }
Exemple #41
0
 private static bool IsOverlapping(Rectangle rectangle, Triangle triangle)
 {
     // Do specialised geometry
     return(true);
 }
Exemple #42
0
 public T Visit(Triangle triangle) => _ifTriangle(triangle);
        public void Triangle_NotExists_Negative()
        {
            Triangle triangle = new Triangle(10, 10, 0);

            var result = _validator.Validate(triangle);
        }
Exemple #44
0
 public void CreateBadValueTriangleTest()
 {
     Triangle triangle = new Triangle(new Point(1, 1), new Point(1, 1), new Point(1, 1));
 }
        public void Triangle_Nigative_All_Parameter_Exception()
        {
            Triangle triangle = new Triangle(-1, -10, -2);

            _validator.Validate(triangle);
        }
Exemple #46
0
 void Update() {
     if (Input.GetKeyDown(KeyCode.R)) {
         t = new Triangle(UR.insideUnitSphere, UR.insideUnitSphere, UR.insideUnitSphere);
         s = new Segment(new Vector3(-1, 0, 0), new Vector3(1, 0, 0));
     }
 }
Exemple #47
0
        public void TestTriangleCheckSquarenessFalse()
        {
            Triangle triangle = new Triangle(5, 3, 3);

            Assert.AreEqual(false, triangle.CheckSquareness());
        }
        public void Triangle_NotExist_Zero_All_Parameters()
        {
            Triangle triangle = new Triangle(0, 0, 0);

            var result = _validator.Validate(triangle);
        }
Exemple #49
0
        public void TestTriangleСalculatingArea()
        {
            Triangle triangle = new Triangle(5, 4, 3);

            Assert.AreEqual(6, triangle.GetArea());
        }
Exemple #50
0
        /// <summary>
        /// Cuts a hole into a shape.
        /// </summary>
        /// <param name="shapeVerts">An array of vertices for the primary shape.</param>
        /// <param name="holeVerts">An array of vertices for the hole to be cut. It is assumed that these vertices lie completely within the shape verts.</param>
        /// <returns>The new array of vertices that can be passed to Triangulate to properly triangulate the shape with the hole.</returns>
        public static Vector2[] CutHoleInShape(Vector2[] shapeVerts, Vector2[] holeVerts)
        {
            Log("\nCutting hole into shape...");

            //make sure the shape vertices are wound counter clockwise and the hole vertices clockwise
            shapeVerts = EnsureWindingOrder(shapeVerts, WindingOrder.CounterClockwise);
            holeVerts  = EnsureWindingOrder(holeVerts, WindingOrder.Clockwise);

            //clear all of the lists
            polygonVertices.Clear();
            earVertices.Clear();
            convexVertices.Clear();
            reflexVertices.Clear();

            //generate the cyclical list of vertices in the polygon
            for (int i = 0; i < shapeVerts.Length; i++)
            {
                polygonVertices.AddLast(new Vertex(shapeVerts[i], (ushort)i));
            }

            CyclicalList <Vertex> holePolygon = new CyclicalList <Vertex>();

            for (int i = 0; i < holeVerts.Length; i++)
            {
                holePolygon.Add(new Vertex(holeVerts[i], (ushort)(i + polygonVertices.Count)));
            }

#if DEBUG
            StringBuilder vString = new StringBuilder();
            foreach (Vertex v in polygonVertices)
            {
                vString.Append(string.Format("{0}, ", v));
            }
            Log("Shape Vertices: {0}", vString);

            vString = new StringBuilder();
            foreach (Vertex v in holePolygon)
            {
                vString.Append(string.Format("{0}, ", v));
            }
            Log("Hole Vertices: {0}", vString);
#endif

            FindConvexAndReflexVertices();
            FindEarVertices();

            //find the hole vertex with the largest X value
            Vertex rightMostHoleVertex = holePolygon[0];
            foreach (Vertex v in holePolygon)
            {
                if (v.Position.X > rightMostHoleVertex.Position.X)
                {
                    rightMostHoleVertex = v;
                }
            }

            //construct a list of all line segments where at least one vertex
            //is to the right of the rightmost hole vertex with one vertex
            //above the hole vertex and one below
            List <LineSegment> segmentsToTest = new List <LineSegment>();
            for (int i = 0; i < polygonVertices.Count; i++)
            {
                Vertex a = polygonVertices[i].Value;
                Vertex b = polygonVertices[i + 1].Value;

                if ((a.Position.X > rightMostHoleVertex.Position.X || b.Position.X > rightMostHoleVertex.Position.X) &&
                    ((a.Position.Y >= rightMostHoleVertex.Position.Y && b.Position.Y <= rightMostHoleVertex.Position.Y) ||
                     (a.Position.Y <= rightMostHoleVertex.Position.Y && b.Position.Y >= rightMostHoleVertex.Position.Y)))
                {
                    segmentsToTest.Add(new LineSegment(a, b));
                }
            }

            //now we try to find the closest intersection point heading to the right from
            //our hole vertex.
            float?      closestPoint   = null;
            LineSegment closestSegment = new LineSegment();
            foreach (LineSegment segment in segmentsToTest)
            {
                float?intersection = segment.IntersectsWithRay(rightMostHoleVertex.Position, Vector2.UnitX);
                if (intersection != null)
                {
                    if (closestPoint == null || closestPoint.Value > intersection.Value)
                    {
                        closestPoint   = intersection;
                        closestSegment = segment;
                    }
                }
            }

            //if closestPoint is null, there were no collisions (likely from improper input data),
            //but we'll just return without doing anything else
            if (closestPoint == null)
            {
                return(shapeVerts);
            }

            //otherwise we can find our mutually visible vertex to split the polygon
            Vector2 I = rightMostHoleVertex.Position + Vector2.UnitX * closestPoint.Value;
            Vertex  P = (closestSegment.A.Position.X > closestSegment.B.Position.X)
                ? closestSegment.A
                : closestSegment.B;

            //construct triangle MIP
            Triangle mip = new Triangle(rightMostHoleVertex, new Vertex(I, 1), P);

            //see if any of the reflex vertices lie inside of the MIP triangle
            List <Vertex> interiorReflexVertices = new List <Vertex>();
            foreach (Vertex v in reflexVertices)
            {
                if (mip.ContainsPoint(v))
                {
                    interiorReflexVertices.Add(v);
                }
            }

            //if there are any interior reflex vertices, find the one that, when connected
            //to our rightMostHoleVertex, forms the line closest to Vector2.UnitX
            if (interiorReflexVertices.Count > 0)
            {
                float closestDot = -1f;
                foreach (Vertex v in interiorReflexVertices)
                {
                    //compute the dot product of the vector against the UnitX
                    Vector2 d   = Vector2.Normalize(v.Position - rightMostHoleVertex.Position);
                    float   dot = Vector2.Dot(Vector2.UnitX, d);

                    //if this line is the closest we've found
                    if (dot > closestDot)
                    {
                        //save the value and save the vertex as P
                        closestDot = dot;
                        P          = v;
                    }
                }
            }

            //now we just form our output array by injecting the hole vertices into place
            //we know we have to inject the hole into the main array after point P going from
            //rightMostHoleVertex around and then back to P.
            int mIndex      = holePolygon.IndexOf(rightMostHoleVertex);
            int injectPoint = polygonVertices.IndexOf(P);

            Log("Inserting hole at injection point {0} starting at hole vertex {1}.",
                P,
                rightMostHoleVertex);
            for (int i = mIndex; i <= mIndex + holePolygon.Count; i++)
            {
                Log("Inserting vertex {0} after vertex {1}.", holePolygon[i], polygonVertices[injectPoint].Value);
                polygonVertices.AddAfter(polygonVertices[injectPoint++], holePolygon[i]);
            }
            polygonVertices.AddAfter(polygonVertices[injectPoint], P);

#if DEBUG
            vString = new StringBuilder();
            foreach (Vertex v in polygonVertices)
            {
                vString.Append(string.Format("{0}, ", v));
            }
            Log("New Shape Vertices: {0}\n", vString);
#endif

            //finally we write out the new polygon vertices and return them out
            Vector2[] newShapeVerts = new Vector2[polygonVertices.Count];
            for (int i = 0; i < polygonVertices.Count; i++)
            {
                newShapeVerts[i] = polygonVertices[i].Value.Position;
            }

            return(newShapeVerts);
        }
Exemple #51
0
 public void TestTriangleWithWrongSides()
 {
     Triangle triangle = new Triangle(5, 4, 10);
 }
Exemple #52
0
        public void TestTriangleCheckSquarenessTrue()
        {
            Triangle triangle = new Triangle(5, 4, 3);

            Assert.AreEqual(true, triangle.CheckSquareness());
        }
Exemple #53
0
        public void Triangle_CalculateArea_BadSides_InvalidOperationException()
        {
            var triangle = new Triangle(2, 2, 8);

            Assert.Throws <InvalidOperationException>(() => triangle.CalculateArea());
        }
Exemple #54
0
        public void TestTriangleСalculatingPerimeter()
        {
            Triangle triangle = new Triangle(5, 4, 3);

            Assert.AreEqual(12, triangle.GetPerimeter());
        }
    /* Smarter implementation, based on the assumption that only contiguous triangles can contain
     *  the point in their circumcircle. Main differences are 1) as we find the first "bad" triangle,
     *  we just check the contiguous ones 2) we need to keep the triangles linked together
     */
    private void ContiguousTriangulate()
    {
        // recursive function to check contiguous if contiguous triangles contain the new point in their circumcircle
        void checkEdges(HashSet <Triangle> _badTriangles, Vector2 point, Triangle triangle)
        {
            for (int edge = 0; edge < 3; edge++)
            {
                if (triangle.links[edge] != null &&
                    triangle.links[edge].isPointInsideCircumcircle(point) &&
                    !_badTriangles.Contains(triangle.links[edge]))
                {
                    _badTriangles.Add(triangle.links[edge]);
                    checkEdges(_badTriangles, point, triangle.links[edge]);
                }
            }
        }

        // find if triangle1 shares one edge with triangle2, and link them
        bool linkTriangles(Triangle triangle1, Triangle triangle2)
        {
            if (triangle1 != triangle2 && triangle1 != null && triangle2 != null)
            {
                for (int outer = 0; outer < 3; outer++)
                {
                    for (int inner = 0; inner < 3; inner++)
                    {
                        if (triangle1.edges[outer].Compare(triangle2.edges[inner]))
                        {
                            triangle1.links[outer] = triangle2;
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }

        triangulation.Clear();
        trianglePool.Clear();
        superTriangle = trianglePool.Get();
        superTriangle.Populate(new Vector2(-halfWidth * 2.5f * scalePlayground, -halfHeight * 2 * scalePlayground),
                               new Vector2(halfWidth * 2.5f * scalePlayground, -halfHeight * 2 * scalePlayground),
                               new Vector2(0.0f, halfHeight * 3 * scalePlayground));
        triangulation.Add(superTriangle);

        List <Edge>        polygon              = new List <Edge>();
        HashSet <Triangle> badTriangles         = new HashSet <Triangle>();
        HashSet <Triangle> outerTriangles       = new HashSet <Triangle>();
        HashSet <Triangle> partialTriangulation = new HashSet <Triangle>();

        for (int i = 0; i < points.Count; i++)
        {
            Vector2 point = points[i].position;

            polygon.Clear();
            badTriangles.Clear();
            outerTriangles.Clear();
            partialTriangulation.Clear();

            foreach (Triangle triangle in triangulation)
            {
                if (triangle.isPointInsideCircumcircle(point))
                {
                    badTriangles.Add(triangle);
                    checkEdges(badTriangles, point, triangle);
                    break;
                }
            }

            foreach (Triangle badTriangle in badTriangles)
            {
                for (int edge = 0; edge < 3; edge++)
                {
                    if (!badTriangles.Contains(badTriangle.links[edge]))
                    {
                        polygon.Add(badTriangle.edges[edge]);
                        // save the link with outer triangles
                        if (badTriangle.links[edge] != null &&
                            !badTriangles.Contains(badTriangle.links[edge]))
                        {
                            outerTriangles.Add(badTriangle.links[edge]);
                        }
                    }
                }
            }

            foreach (Triangle badTriangle in badTriangles)
            {
                trianglePool.Remove(badTriangle);
                triangulation.Remove(badTriangle);
            }

            // insert new triangles into a "partial" triangulation, allowing for linking
            for (int j = 0; j < polygon.Count; j++)
            {
                Triangle thisTriangle = trianglePool.Get();
                thisTriangle.Populate(polygon[j].A, polygon[j].B, point);
                partialTriangulation.Add(thisTriangle);
            }

            foreach (Triangle partialTriangle in partialTriangulation)
            {
                // link with outer triangles
                foreach (Triangle outerTriangle in outerTriangles)
                {
                    if (linkTriangles(partialTriangle, outerTriangle))
                    {
                        linkTriangles(outerTriangle, partialTriangle);
                        break;
                    }
                }

                // link "partial" triangles with each other
                int maxTwoLinked = 0;
                foreach (Triangle otherPartialTriangle in partialTriangulation)
                {
                    if (linkTriangles(partialTriangle, otherPartialTriangle))
                    {
                        maxTwoLinked++;
                    }
                    if (maxTwoLinked == 2)
                    {
                        break;
                    }
                }

                triangulation.Add(partialTriangle);
            }
        }
    }
Exemple #56
0
 public void TestTriangleWithNegativeSide()
 {
     Triangle triangle = new Triangle(5, 4, -2);
 }
Exemple #57
0
        /// <summary>
        /// DoOverlapBoxTriangleTest
        /// </summary>
        /// <param name="oldBox"></param>
        /// <param name="newBox"></param>
        /// <param name="triangle"></param>
        /// <param name="mesh"></param>
        /// <param name="info"></param>
        /// <param name="collTolerance"></param>
        /// <param name="collisionFunctor"></param>
        /// <returns>bool</returns>
        private static bool DoOverlapBoxTriangleTest(Box oldBox, Box newBox,
                                                     ref IndexedTriangle triangle, TriangleMesh mesh,
                                                     ref CollDetectInfo info, float collTolerance,
                                                     CollisionFunctor collisionFunctor)
        {
            Matrix dirs0 = newBox.Orientation;

            #region REFERENCE: Triangle tri = new Triangle(mesh.GetVertex(triangle.GetVertexIndex(0)),mesh.GetVertex(triangle.GetVertexIndex(1)),mesh.GetVertex(triangle.GetVertexIndex(2)));
            Vector3 triVec0;
            Vector3 triVec1;
            Vector3 triVec2;
            mesh.GetVertex(triangle.GetVertexIndex(0), out triVec0);
            mesh.GetVertex(triangle.GetVertexIndex(1), out triVec1);
            mesh.GetVertex(triangle.GetVertexIndex(2), out triVec2);

            // Deano move tri into world space
            Matrix transformMatrix = mesh.TransformMatrix;
            Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
            Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
            Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);

            Triangle tri = new Triangle(ref triVec0, ref triVec1, ref triVec2);
            #endregion


            #region REFERENCE Vector3 triEdge0 = (tri.GetPoint(1) - tri.GetPoint(0));
            Vector3 pt0;
            Vector3 pt1;
            tri.GetPoint(0, out pt0);
            tri.GetPoint(1, out pt1);

            Vector3 triEdge0;
            Vector3.Subtract(ref pt1, ref pt0, out triEdge0);
            #endregion

            #region REFERENCE Vector3 triEdge1 = (tri.GetPoint(2) - tri.GetPoint(1));
            Vector3 pt2;
            tri.GetPoint(2, out pt2);

            Vector3 triEdge1;
            Vector3.Subtract(ref pt2, ref pt1, out triEdge1);
            #endregion

            #region REFERENCE Vector3 triEdge2 = (tri.GetPoint(0) - tri.GetPoint(2));
            Vector3 triEdge2;
            Vector3.Subtract(ref pt0, ref pt2, out triEdge2);
            #endregion

            triEdge0.Normalize();
            triEdge1.Normalize();
            triEdge2.Normalize();


            // BEN-OPTIMISATION: Replaced loops with code that requires no looping.
            //                   The new code is faster, has less allocations and math especially
            //                   since the method returns as soon as it finds a non-overlapping axis,
            //                   i.e. Before irreleveat allocations occur.
            #region "Old (less efficient) code"

            /*Vector3 triNormal = triangle.Plane.Normal;
             *
             * // the 15 potential separating axes
             * const int numAxes = 13;
             * Vector3[] axes = new Vector3[numAxes];
             *
             * axes[0] = triNormal;
             * axes[1] = dirs0.Right;
             * axes[2] = dirs0.Up;
             * axes[3] = dirs0.Backward;
             * Vector3.Cross(ref axes[1], ref triEdge0, out axes[4]);
             * Vector3.Cross(ref axes[1], ref triEdge1, out axes[5]);
             * Vector3.Cross(ref axes[1], ref triEdge2, out axes[6]);
             * Vector3.Cross(ref axes[2], ref triEdge0, out axes[7]);
             * Vector3.Cross(ref axes[2], ref triEdge1, out axes[8]);
             * Vector3.Cross(ref axes[2], ref triEdge2, out axes[9]);
             * Vector3.Cross(ref axes[3], ref triEdge0, out axes[10]);
             * Vector3.Cross(ref axes[3], ref triEdge1, out axes[11]);
             * Vector3.Cross(ref axes[3], ref triEdge2, out axes[12]);
             *
             * // the overlap depths along each axis
             * float[] overlapDepths = new float[numAxes];
             *
             * // see if the boxes are separate along any axis, and if not keep a
             * // record of the depths along each axis
             * int i;
             * for (i = 0; i < numAxes; ++i)
             * {
             *  overlapDepths[i] = 1.0f;
             *  if (Disjoint(out overlapDepths[i], axes[i], newBox, tri, collTolerance))
             *      return false;
             * }
             *
             * // The box overlap, find the separation depth closest to 0.
             * float minDepth = float.MaxValue;
             * int minAxis = -1;
             *
             * for (i = 0; i < numAxes; ++i)
             * {
             *  // If we can't normalise the axis, skip it
             *  float l2 = axes[i].LengthSquared();
             *  if (l2 < JiggleMath.Epsilon)
             *      continue;
             *
             *  // Normalise the separation axis and the depth
             *  float invl = 1.0f / (float)System.Math.Sqrt(l2);
             *  axes[i] *= invl;
             *  overlapDepths[i] *= invl;
             *
             *  // If this axis is the minimum, select it
             *  if (overlapDepths[i] < minDepth)
             *  {
             *      minDepth = overlapDepths[i];
             *      minAxis = i;
             *  }
             * }
             *
             * if (minAxis == -1)
             *  return false;
             *
             * // Make sure the axis is facing towards the 0th box.
             * // if not, invert it
             * Vector3 D = newBox.GetCentre() - tri.Centre;
             * Vector3 N = axes[minAxis];
             * float depth = overlapDepths[minAxis];*/
            #endregion
            #region "Optimised code"
            Vector3 triNormal = triangle.Plane.Normal;
            Vector3 right     = dirs0.Right;
            Vector3 up        = dirs0.Up;
            Vector3 backward  = dirs0.Backward;

            float testDepth;

            if (Disjoint(out testDepth, ref triNormal, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            float   depth = testDepth;
            Vector3 N     = triNormal;

            if (Disjoint(out testDepth, ref right, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            if (testDepth < depth)
            {
                depth = testDepth;
                N     = right;
            }

            if (Disjoint(out testDepth, ref up, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            if (testDepth < depth)
            {
                depth = testDepth;
                N     = up;
            }

            if (Disjoint(out testDepth, ref backward, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            if (testDepth < depth)
            {
                depth = testDepth;
                N     = backward;
            }

            Vector3 axis;

            Vector3.Cross(ref right, ref triEdge0, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            Vector3.Cross(ref right, ref triEdge1, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            Vector3.Cross(ref right, ref triEdge2, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            Vector3.Cross(ref up, ref triEdge0, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            Vector3.Cross(ref up, ref triEdge1, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            Vector3.Cross(ref up, ref triEdge2, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            Vector3.Cross(ref backward, ref triEdge0, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            Vector3.Cross(ref backward, ref triEdge1, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            Vector3.Cross(ref backward, ref triEdge2, out axis);
            if (Disjoint(out testDepth, ref axis, newBox, ref tri, collTolerance))
            {
                return(false);
            }

            testDepth *= 1.0f / (float)System.Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
            if (testDepth < depth)
            {
                depth = testDepth;
                N     = axis;
            }

            /*if (N == Vector3.Zero)
             *  return (false);*/

            Vector3 D = newBox.GetCentre() - tri.Centre;
            N.Normalize();
            int i;

            #endregion

            if (Vector3.Dot(D, N) < 0.0f)
            {
                N *= -1;
            }

            Vector3 boxOldPos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 boxNewPos = (info.Skin0.Owner != null) ? info.Skin0.Owner.Position : Vector3.Zero;
            Vector3 meshPos   = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            List <Vector3> pts = new List <Vector3>();
            //pts.Clear();

            const float combinationDist = 0.05f;
            GetBoxTriangleIntersectionPoints(pts, newBox, tri, depth + combinationDist);

            // adjust the depth
            #region REFERENCE: Vector3 delta = boxNewPos - boxOldPos;
            Vector3 delta;
            Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta);
            #endregion

            #region REFERENCE: float oldDepth = depth + Vector3.Dot(delta, N);
            float oldDepth;
            Vector3.Dot(ref delta, ref N, out oldDepth);
            oldDepth += depth;
            #endregion

            unsafe
            {
                // report collisions
                int numPts = pts.Count;
#if USE_STACKALLOC
                SmallCollPointInfo *collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
#else
                SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                fixed(SmallCollPointInfo *collPts = collPtArray)
#endif
                {
                    if (numPts > 0)
                    {
                        if (numPts >= MaxLocalStackSCPI)
                        {
                            numPts = MaxLocalStackSCPI - 1;
                        }

                        // adjust positions
                        for (i = 0; i < numPts; ++i)
                        {
                            // BEN-OPTIMISATION: Reused existing SmallCollPointInfo and inlined vector substraction.
                            collPts[i].R0.X = pts[i].X - boxNewPos.X;
                            collPts[i].R0.Y = pts[i].Y - boxNewPos.Y;
                            collPts[i].R0.Z = pts[i].Z - boxNewPos.Z;

                            collPts[i].R1.X = pts[i].X - meshPos.X;
                            collPts[i].R1.Y = pts[i].Y - meshPos.Y;
                            collPts[i].R1.Z = pts[i].Z - meshPos.Z;

                            collPts[i].InitialPenetration = oldDepth;
                        }

                        collisionFunctor.CollisionNotify(ref info, ref N, collPts, numPts);
#if !USE_STACKALLOC
                        FreeStackAlloc(collPtArray);
#endif
                        return(true);
                    }
                    else
                    {
#if !USE_STACKALLOC
                        FreeStackAlloc(collPtArray);
#endif
                        return(false);
                    }
                }
            }
        }
Exemple #58
0
        public void Triangle_CalculateArea_NegativeSide_ArgumentOutOfRangeException()
        {
            var triangle = new Triangle(-1, 4, 6);

            Assert.Throws <ArgumentOutOfRangeException>(() => triangle.CalculateArea());
        }
    public void MakeMesh()
    {
        IEnumerator <Triangle> triangleEnumerator = mesh.Triangles.GetEnumerator();

        for (int chunkStart = 0; chunkStart < mesh.Triangles.Count; chunkStart += trianglesInChunk)
        {
            List <Vector3> vertices  = new List <Vector3>();
            List <Vector3> normals   = new List <Vector3>();
            List <Vector2> uvs       = new List <Vector2>();
            List <int>     triangles = new List <int>();

            int chunkEnd = chunkStart + trianglesInChunk;
            for (int i = chunkStart; i < chunkEnd; i++)
            {
                if (!triangleEnumerator.MoveNext())
                {
                    break;
                }

                Triangle triangle = triangleEnumerator.Current;

                // For the triangles to be right-side up, they need
                // to be wound in the opposite direction
                Vector3 v0 = GetPoint3D(triangle.vertices[2].id);
                Vector3 v1 = GetPoint3D(triangle.vertices[1].id);
                Vector3 v2 = GetPoint3D(triangle.vertices[0].id);

                triangles.Add(vertices.Count);
                triangles.Add(vertices.Count + 1);
                triangles.Add(vertices.Count + 2);

                vertices.Add(v0);
                vertices.Add(v1);
                vertices.Add(v2);

                Vector3 normal = Vector3.Cross(v1 - v0, v2 - v0);
                normals.Add(normal);
                normals.Add(normal);
                normals.Add(normal);

                uvs.Add(new Vector2(0.0f, 0.0f));
                uvs.Add(new Vector2(0.0f, 0.0f));
                uvs.Add(new Vector2(0.0f, 0.0f));
            }

            Mesh chunkMesh = new Mesh();
            chunkMesh.vertices  = vertices.ToArray();
            chunkMesh.uv        = uvs.ToArray();
            chunkMesh.triangles = triangles.ToArray();
            chunkMesh.normals   = normals.ToArray();

            Transform chunk = Instantiate <Transform>(chunkPrefab, transform.position, transform.rotation);
            chunk.GetComponent <MeshFilter>().mesh         = chunkMesh;
            chunk.GetComponent <MeshCollider>().sharedMesh = chunkMesh;
            chunk.transform.parent = transform;

            foreach (MatLayer l in materials)
            {
                if (l.Assign(vertices))
                {
                    chunk.GetComponent <MeshRenderer>().material = l.material;
                }
            }
        }
    }
    /* loop through each point to add, brute force search through each triangle, if
     *  the point is contained in the triangle's circumcircle remove it. Create a polygon with
     *  each removed triangle's outer edge, and add the triangles made by linking each edge to
     *  the new point
     */
    private void Triangulate()
    {
        triangulation.Clear();
        trianglePool.Clear();
        // first triangle, containing the whole playground
        superTriangle = trianglePool.Get();
        superTriangle.Populate(new Vector2(-halfWidth * 2.5f * scalePlayground, -halfHeight * 2 * scalePlayground),
                               new Vector2(halfWidth * 2.5f * scalePlayground, -halfHeight * 2 * scalePlayground),
                               new Vector2(0.0f, halfHeight * 3 * scalePlayground));
        triangulation.Add(superTriangle);

        List <Triangle> badTriangles = new List <Triangle>();
        List <Edge>     polygon      = new List <Edge>();

        for (int i = 0; i < points.Count; i++)
        {
            Vector2 point = points[i].position;
            badTriangles.Clear();
            polygon.Clear();

            // check if the triangle contains point in its circumcircle
            foreach (Triangle triangle in triangulation)
            {
                if (triangle.isPointInsideCircumcircle(point))
                {
                    badTriangles.Add(triangle);
                }
            }

            // create the outer polygon
            for (int outer = 0; outer < badTriangles.Count; outer++)
            {
                for (int edge = 0; edge < 3; edge++)
                {
                    bool isShared = false;
                    for (int inner = 0; inner < badTriangles.Count; inner++)
                    {
                        if (inner != outer && !isShared)
                        {
                            for (int badEdge = 0; badEdge < 3; badEdge++)
                            {
                                if (badTriangles[outer].edges[edge].Compare(badTriangles[inner].edges[badEdge]))
                                {
                                    isShared = true;
                                }
                            }
                        }
                    }
                    if (!isShared)
                    {
                        polygon.Add(badTriangles[outer].edges[edge]);
                    }
                }
            }

            // remove bad triangles
            for (int j = 0; j < badTriangles.Count; j++)
            {
                trianglePool.Remove(badTriangles[j]);
                triangulation.Remove(badTriangles[j]);
            }

            // create new triangles
            for (int j = 0; j < polygon.Count; j++)
            {
                Triangle thisTriangle = trianglePool.Get();
                thisTriangle.Populate(polygon[j].A, polygon[j].B, point);
                triangulation.Add(thisTriangle);
            }
        }
    }