Ejemplo n.º 1
0
        public void Cross()
        {
            Vector2f v01 = new Vector2f(0, 1);
            Vector2f v10 = new Vector2f(1, 0);

            Assert.AreEqual(Vector2f.Cross(v01, v10), -1.0f);
        }
Ejemplo n.º 2
0
        public void CalculateCircumcircle(IList <Vector2f> vertices)
        {
            Vector2f p = vertices[i0];
            Vector2f q = vertices[i1];
            Vector2f r = vertices[i2];

            // calculate the intersection of two perpendicular bisectors
            Vector2f pq = q - p;
            Vector2f qr = r - q;

            // check winding
            if (Vector2f.Cross(pq, qr) < 0.0f)
            {
                throw new InvalidOperationException("Triangle winding order incorrect");
            }

            // mid-points of  edges
            Vector2f a = 0.5f * (p + q);
            Vector2f b = 0.5f * (q + r);
            Vector2f u = pq.PerpendicularCCW;

            float d = Vector2f.Dot(u, qr);
            float t = Vector2f.Dot(b - a, qr) / d;

            CircumCenter = a + t * u;
            CircumRadius = (CircumCenter - p).Magnitude;
        }
Ejemplo n.º 3
0
        public float TriArea(IList <Vector2f> vertices)
        {
            Vector2f a = vertices[i0];
            Vector2f b = vertices[i1];
            Vector2f c = vertices[i2];

            return(0.5f * (Vector2f.Cross(b - a, c - a)));
        }
Ejemplo n.º 4
0
        public static bool TriangleContainsPointCCW(Triangle2f triangle, Vector2f p)
        {
            if (Vector2f.Cross(p - triangle.A, triangle.B - triangle.A) > 0.0)
            {
                return(false);
            }
            if (Vector2f.Cross(p - triangle.B, triangle.C - triangle.B) > 0.0)
            {
                return(false);
            }
            if (Vector2f.Cross(p - triangle.C, triangle.A - triangle.C) > 0.0)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 5
0
        public static bool TriangleContainsPoint(Triangle2f triangle, Vector2f p)
        {
            float pab = Vector2f.Cross(p - triangle.A, triangle.B - triangle.A);
            float pbc = Vector2f.Cross(p - triangle.B, triangle.C - triangle.B);

            if (Math.Sign(pab) != Math.Sign(pbc))
            {
                return(false);
            }

            float pca = Vector2f.Cross(p - triangle.C, triangle.A - triangle.C);

            if (Math.Sign(pab) != Math.Sign(pca))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 6
0
        // apply a force at 'fromCenter' relative to center of the shape
        public void ApplyTorque(Vector2f force, Vector2f fromCenter)
        {
            var radius = fromCenter.Magnitude();

            // check if 'fromCenter' is outside of the shape.
            if(radius > GetRadiusOn(fromCenter))
                return;

            // torque is the amount of force in the perpendicular direction
            var torque = force.Cross(fromCenter);

            // linear force is the amount of force in the parallel direction
            var linearForce = force.Dot(fromCenter) / (radius != 0 ? radius : 1f);

            // moment of inertia of the mass at this radius
            var inertia = mass * radius * radius;

            AngularAcceleration += -torque / (inertia != 0 ? inertia : 1);
            ApplyForce(linearForce * force.Unit());
        }
Ejemplo n.º 7
0
 public static float Cross(Vector2f a, Vector2f b)
 {
     return(Vector2f.Cross(a, b));
 }
Ejemplo n.º 8
0
        public PConvexPolygonShape(float[] xvers, float[] yvers, float density)
        {
            float[] xs = (float[])xvers.Clone();
            float[] ys = (float[])yvers.Clone();
            numVertices = xs.Length;
            _dens       = density;
            localVers   = new Vector2f[numVertices];
            nors        = new Vector2f[numVertices];
            float fakeCenterY;
            float fakeCenterX = fakeCenterY = 0.0F;

            for (int i = 0; i < numVertices; i++)
            {
                fakeCenterX += xs[i];
                fakeCenterY += ys[i];
            }

            fakeCenterX /= numVertices;
            fakeCenterY /= numVertices;
            for (int i = 0; i < numVertices; i++)
            {
                localVers[i] = new Vector2f(xs[i] - fakeCenterX, ys[i]
                                            - fakeCenterY);
                nors[i] = new Vector2f();
            }

            vers = new Vector2f[numVertices];
            for (int j = 0; j < localVers.Length; j++)
            {
                mm += localVers[j].Cross(localVers[(j + 1) % numVertices]) * 0.5F;
            }

            float cy;
            float cx       = cy = 0.0F;
            float invThree = 0.3333333F;

            for (int j = 0; j < localVers.Length; j++)
            {
                Vector2f ver     = localVers[j];
                Vector2f nextVer = localVers[(j + 1) % numVertices];
                float    triArea = ver.Cross(nextVer) * 0.5F;
                cx += triArea * (ver.x + nextVer.x) * invThree;
                cy += triArea * (ver.y + nextVer.y) * invThree;
            }

            float invM = 1.0F / mm;

            cx *= invM;
            cy *= invM;
            cx += fakeCenterX;
            cy += fakeCenterY;
            for (int i = 0; i < numVertices; i++)
            {
                localVers[i].x += fakeCenterX;
                localVers[i].y += fakeCenterY;
            }

            _localPos.Set(cx, cy);
            for (int i = 0; i < numVertices; i++)
            {
                vers[i] = new Vector2f(localVers[i].x, localVers[i].y);
            }
            for (int i = 0; i < numVertices; i++)
            {
                localVers[i].SubLocal(_localPos);
            }

            float invSix = 0.1666667F;

            for (int j = 0; j < localVers.Length; j++)
            {
                Vector2f ver     = localVers[j];
                Vector2f nextVer = localVers[(j + 1) % numVertices];
                float    triArea = ver.Cross(nextVer) * 0.5F;
                this.ii += triArea
                           * invSix
                           * (ver.x * ver.x + ver.y * ver.y + ver.x * nextVer.x
                              + ver.y * nextVer.y + nextVer.x * nextVer.x + nextVer.y
                              * nextVer.y);
            }

            localNors = new Vector2f[numVertices];
            for (int i = 0; i < numVertices; i++)
            {
                Vector2f ver     = localVers[i];
                Vector2f nextVer = localVers[(i + 1) % localVers.Length];
                localNors[i] = new Vector2f(nextVer.y - ver.y, -nextVer.x + ver.x);
                localNors[i].Normalize();
            }

            _type = PShapeType.CONVEX_SHAPE;
            SetDensity(_dens);
            CalcAABB();
        }
Ejemplo n.º 9
0
        public static FEMScene Create(Texture2D img)
        {
            FEMScene Scene = new FEMScene();

            if (img == null)
            {
                return(Scene);
            }

            Scene.Substeps   = 80;
            Scene.Drag       = 0.1f;
            Scene.LameLambda = 42000.0f;
            Scene.LameMu     = 42000.0f;
            Scene.Damping    = 250.0f;
            Scene.Friction   = 0.8f;
            Scene.Toughness  = 40000.0f;

            List <Vector2f> points  = new List <Vector2f>();
            List <Vector2f> bpoints = new List <Vector2f>();

            // controls how finely the object is sampled
            aspect = (float)img.height / img.width;

            float fw = img.width;
            float fh = img.height;

            int inc    = Mathf.FloorToInt(img.width * resolution);
            int margin = Mathf.Max((inc - 1) / 2, 1);

            // distribute points interior to the object or near it's boundary
            for (int y = 0; y < img.height; y += inc)
            {
                for (int x = 0; x < img.width; x += inc)
                {
                    // if value non-zero then add a point
                    int n = Neighbours(img, x, y, margin);

                    if (n > 0)
                    {
                        Vector2f uv = new Vector2f(x / fw, y / fh);
                        points.Add(uv);
                    }
                }
            }

            // distribute points on the boundary
            for (int y = 0; y < img.height; y++)
            {
                for (int x = 0; x < img.width; x++)
                {
                    if (EdgeDetect(img, x, y))
                    {
                        Vector2f uv = new Vector2f(x / fw, y / fh);
                        bpoints.Add(uv);
                    }
                }
            }

            // triangulate
            int iterations = 7;

            List <Vector2f> verts;
            List <int>      tris;

            Mesher.TriangulateVariational(points, bpoints, iterations, out verts, out tris);

            //no longer used
            points  = null;
            bpoints = null;

            // discard triangles whose centroid is not inside the shape
            for (int i = 0; i < tris.Count;)
            {
                Vector2f p = verts[tris[i + 0]];
                Vector2f q = verts[tris[i + 1]];
                Vector2f r = verts[tris[i + 2]];

                Vector2f c = (p + q + r) / 3.0f;

                //int x = Mathf.FloorToInt(c.x * fw);
                //int y = Mathf.FloorToInt(c.y * fh);
                //Color col = img.GetPixel(x, y);

                Color col = img.GetPixelBilinear(c.x, c.y);

                if (col.grayscale == 0.0f)
                {
                    tris.RemoveRange(i, 3);
                }
                else
                {
                    i += 3;
                }
            }

            // generate particles
            for (int i = 0; i < verts.Count; ++i)
            {
                Vector2f uv = verts[i];
                Scene.Particles.Add(new FEMParticle(ToWorldPos(uv), uv, 0.0f));
            }

            // generate elements and assign mass based on connected area
            for (int t = 0; t < tris.Count; t += 3)
            {
                int i = tris[t];
                int j = tris[t + 1];
                int k = tris[t + 2];

                // calculate tri area
                Vector2f a = Scene.Particles[i].p;
                Vector2f b = Scene.Particles[j].p;
                Vector2f c = Scene.Particles[k].p;

                float area = 0.5f * Vector2f.Cross(b - a, c - a);
                float mass = density * area / 3.0f;

                Scene.Particles[i].invMass += mass;
                Scene.Particles[j].invMass += mass;
                Scene.Particles[k].invMass += mass;

                Scene.Triangles.Add(new Triangle(i, j, k));
            }

            // convert mass to invmass
            for (int i = 0; i < Scene.Particles.Count; ++i)
            {
                if (Scene.Particles[i].invMass > 0.0f)
                {
                    Scene.Particles[i].invMass = 1.0f / Scene.Particles[i].invMass;
                }
            }

            // assign index to particles
            for (int i = 0; i < Scene.Particles.Count; ++i)
            {
                Scene.Particles[i].index = i;
            }

            Scene.CreateElements();

            return(Scene);
        }
Ejemplo n.º 10
0
 private float CalcArea(Vector2f v1, Vector2f v2, Vector2f v3)
 {
     return((v1.Cross(v2) + v2.Cross(v3) + v3.Cross(v1)) * 0.5F);
 }