Пример #1
0
        public void GetRow()
        {
            Matrix2x2f m = Indexed2x2();

            Assert.AreEqual(new Vector2f(0, 2), m.GetRow(0));
            Assert.AreEqual(new Vector2f(1, 3), m.GetRow(1));
        }
Пример #2
0
        public void GetColumn()
        {
            Matrix2x2f m = Indexed2x2();

            Assert.AreEqual(new Vector2f(0, 1), m.GetColumn(0));
            Assert.AreEqual(new Vector2f(2, 3), m.GetColumn(1));
        }
Пример #3
0
        public void Transform(Matrix2x2f m)
        {
            int numVerts = Vertices.Count;

            for (int i = 0; i < numVerts; i++)
            {
                Vertices[i].Transform(m);
            }
        }
Пример #4
0
        public void TryInverse()
        {
            Matrix2x2f m       = Random2x2(0);
            Matrix2x2f inverse = Matrix2x2f.Identity;

            m.TryInverse(ref inverse);

            Assert.IsTrue((inverse * Random2x2(0)).EqualsWithError(Matrix2x2f.Identity, 1e-6f));
        }
Пример #5
0
        public static void EigenDecomposition(Matrix2x2f m, out float e1, out float e2)
        {
            // solve the characteristic polynomial
            float a = 1.0f;
            float b = -(m.m00 + m.m11);
            float c = m.m00 * m.m11 - m.m01 * m.m10;

            SolveQuadratic(a, b, c, out e1, out e2);
        }
Пример #6
0
        public void SetRowt()
        {
            Matrix2x2f m = new Matrix2x2f();

            m.SetRow(0, new Vector2f(0, 2));
            m.SetRow(1, new Vector2f(1, 3));

            Assert.AreEqual(new Vector2f(0, 2), m.GetRow(0));
            Assert.AreEqual(new Vector2f(1, 3), m.GetRow(1));
        }
Пример #7
0
        public void SetColumn()
        {
            Matrix2x2f m = new Matrix2x2f();

            m.SetColumn(0, new Vector2f(0, 1));
            m.SetColumn(1, new Vector2f(2, 3));

            Assert.AreEqual(new Vector2f(0, 1), m.GetColumn(0));
            Assert.AreEqual(new Vector2f(2, 3), m.GetColumn(1));
        }
Пример #8
0
        public void CreatedFromValues()
        {
            Matrix2x2f m = new Matrix2x2f(0, 2,
                                          1, 3);

            for (int i = 0; i < SIZE; i++)
            {
                Assert.AreEqual(i, m[i]);
            }
        }
Пример #9
0
        public void MCreatedFromSingleValue()
        {
            float      v = 1;
            Matrix2x2f m = new Matrix2x2f(v);

            for (int i = 0; i < SIZE; i++)
            {
                Assert.AreEqual(v, m[i]);
            }
        }
Пример #10
0
        public static Matrix2x2f QRDecomposition(Matrix2x2f m)
        {
            Vector2f   a = m.GetColumn(0).Normalized;
            Matrix2x2f q = new Matrix2x2f();

            q.SetColumn(0, a);
            q.SetColumn(1, a.PerpendicularCCW);

            return(q);
        }
Пример #11
0
        Matrix2x2f Indexed2x2()
        {
            Matrix2x2f m = new Matrix2x2f();

            for (int i = 0; i < SIZE; i++)
            {
                m[i] = i;
            }

            return(m);
        }
Пример #12
0
        public void CreatedFromArray()
        {
            float[] d = new float[] { 0, 1, 2, 3 };

            Matrix2x2f m = new Matrix2x2f(d);

            for (int i = 0; i < SIZE; i++)
            {
                Assert.AreEqual(i, m[i]);
            }
        }
Пример #13
0
        float FrobeniusNorm(Matrix2x2f m)
        {
            float f = 0.0f;

            for (int i = 0; i < 2; ++i)
            {
                for (int j = 0; j < 2; ++j)
                {
                    f += m[i, j] * m[i, j];
                }
            }

            return((float)Math.Sqrt(f));
        }
Пример #14
0
        public void Transpose()
        {
            Matrix2x2f m = new Matrix2x2f();

            for (int i = 0; i < HALF_SIZE; i++)
            {
                for (int j = 0; j < HALF_SIZE; j++)
                {
                    m[j, i] = i + j * HALF_SIZE;
                }
            }

            Assert.AreEqual(Indexed2x2().Transpose, m);
        }
Пример #15
0
        public void IndexAssignedTo()
        {
            Matrix2x2f m = new Matrix2x2f();

            for (int i = 0; i < SIZE; i++)
            {
                m[i] = i;
            }

            for (int i = 0; i < SIZE; i++)
            {
                Assert.AreEqual(i, m[i]);
            }
        }
Пример #16
0
        public void CreatedFromArray2()
        {
            float[,] d = new float[, ] {
                { 0, 2 },
                { 1, 3 }
            };

            Matrix2x2f m = new Matrix2x2f(d);

            for (int i = 0; i < SIZE; i++)
            {
                Assert.AreEqual(i, m[i]);
            }
        }
Пример #17
0
        public static Matrix2x2f PolarDecomposition(Matrix2x2f m)
        {
            Matrix2x2f q = m + new Matrix2x2f(m.m11, -m.m10, -m.m01, m.m00);

            Vector2f c0 = q.GetColumn(0);
            Vector2f c1 = q.GetColumn(1);

            float s = c0.Magnitude;

            q.SetColumn(0, c0 / s);
            q.SetColumn(1, c1 / s);

            return(q);
        }
Пример #18
0
        /// <summary>
        /// deformation gradient
        /// </summary>
        private Matrix2x2f CalcDeformation(Vector2f[] x, Matrix2x2f invM)
        {
            Vector2f e1 = x[1] - x[0];
            Vector2f e2 = x[2] - x[0];

            Matrix2x2f m = new Matrix2x2f();

            m.SetColumn(0, e1);
            m.SetColumn(1, e2);

            // mapping from material coordinates to world coordinates
            Matrix2x2f f = m * invM;

            return(f);
        }
Пример #19
0
        Matrix2x2f Random2x2(int seed)
        {
            Random     rnd = new Random(seed);
            Matrix2x2f m   = new Matrix2x2f();

            for (int i = 0; i < HALF_SIZE; i++)
            {
                for (int j = 0; j < HALF_SIZE; j++)
                {
                    m[i, j] = (float)rnd.NextDouble();
                }
            }

            return(m);
        }
Пример #20
0
        public FEMElement(Vector2f[] x)
        {
            Vector2f e1 = x[1] - x[0];
            Vector2f e2 = x[2] - x[0];
            Vector2f e3 = x[2] - x[1];

            Matrix2x2f m = new Matrix2x2f();

            m.SetColumn(0, e1);
            m.SetColumn(1, e2);

            mInvDm = m.Inverse;

            mB    = new Vector2f[3];
            mB[0] = e3.PerpendicularCCW;
            mB[1] = e2.PerpendicularCW;
            mB[2] = e1.PerpendicularCCW;
        }
Пример #21
0
        public void Index2AssignedTo()
        {
            Matrix2x2f m = new Matrix2x2f();

            for (int i = 0; i < HALF_SIZE; i++)
            {
                for (int j = 0; j < HALF_SIZE; j++)
                {
                    m[i, j] = i + j * HALF_SIZE;
                }
            }

            for (int i = 0; i < HALF_SIZE; i++)
            {
                for (int j = 0; j < HALF_SIZE; j++)
                {
                    Assert.AreEqual(i + j * HALF_SIZE, m[i, j]);
                }
            }
        }
Пример #22
0
        /// <summary>
        /// Creates matrix fixed.
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public Float2x2 Fixed(Matrix2x2f m)
        {
            ConstantOperation c = dag.CreateFixed(m);

            return(new Float2x2(c.Outputs[0], this));
        }
Пример #23
0
 public virtual void Transform(Matrix2x2f m)
 {
 }
Пример #24
0
 public override void Transform(Matrix2x2f m)
 {
     Position = m * Position;
 }
Пример #25
0
        /// <summary>
        /// calculate Green's non-linear strain tensor
        /// </summary>
        private Matrix2x2f CalcGreenStrainTensor(Matrix2x2f f)
        {
            Matrix2x2f e = (f.Transpose * f - Matrix2x2f.Identity) * 0.5f;

            return(e);
        }
Пример #26
0
        private void UpdateForces(float dt, bool performFracture)
        {
            for (int i = 0; i < Particles.Count; ++i)
            {
                Particles[i].max = 0;

                if (Particles[i].invMass > 0.0f)
                {
                    Particles[i].f += Gravity / Particles[i].invMass;
                }
                else
                {
                    Particles[i].f += Vector2f.Zero - Drag * Particles[i].v;
                }
            }

            Vector2f[] x = new Vector2f[3];
            Vector2f[] v = new Vector2f[3];

            for (int i = 0; i < Triangles.Count; ++i)
            {
                Triangle   tri  = Triangles[i];
                FEMElement elem = Elements[i];

                x[0] = Particles[tri.i].p;
                x[1] = Particles[tri.j].p;
                x[2] = Particles[tri.k].p;

                v[0] = Particles[tri.i].v;
                v[1] = Particles[tri.j].v;
                v[2] = Particles[tri.k].v;

                if (performFracture)
                {
                    Matrix2x2f f = CalcDeformation(x, elem.mInvDm);
                    Matrix2x2f q = Decomposition2x2f.QRDecomposition(f);

                    // strain
                    Matrix2x2f e = CalcCauchyStrainTensor(q.Transpose * f);

                    // update plastic strain
                    float ef = FrobeniusNorm(e);

                    if (ef > Yield)
                    {
                        elem.mEp += e * dt * Creep;
                    }

                    const float epmax = 0.6f;
                    if (ef > epmax)
                    {
                        elem.mEp *= epmax / ef;
                    }

                    // adjust strain
                    e -= elem.mEp;

                    Matrix2x2f s = CalcStressTensor(e, LameLambda, LameMu);

                    // damping forces
                    Matrix2x2f dfdt = CalcDeformation(v, elem.mInvDm);
                    Matrix2x2f dedt = CalcCauchyStrainTensorDt(q.Transpose * dfdt);
                    Matrix2x2f dsdt = CalcStressTensor(dedt, Damping, Damping);

                    Matrix2x2f p = s + dsdt;

                    float e1, e2;
                    Decomposition2x2f.EigenDecomposition(p, out e1, out e2);

                    float me = Mathf.Max(e1, e2);

                    if (me > Toughness)
                    {
                        // calculate Eigenvector corresponding to max Eigenvalue
                        Vector2f ev = q * (new Vector2f(p.m01, me - p.m00)).Normalized;

                        // pick a random vertex to split on
                        int splitNode = Rnd.Next(0, 2);

                        // don't fracture immovable nodes
                        if (Particles[GetVertex(tri, splitNode)].invMass == 0.0f)
                        {
                            break;
                        }

                        // fracture plane perpendicular to ev
                        Vector3f plane = new Vector3f(ev.x, ev.y, -Vector2f.Dot(ev, Particles[GetVertex(tri, splitNode)].p));

                        FEMFractureEvent fracture = new FEMFractureEvent();
                        fracture.Tri   = i;
                        fracture.Node  = splitNode;
                        fracture.Plane = plane;

                        //Fracture not implemented so these fracture planes are not used.
                        Fractures.Add(fracture);
                    }

                    // calculate force on each edge due to stress and distribute to the nodes
                    Vector2f f1 = q * p * elem.mB[0];
                    Vector2f f2 = q * p * elem.mB[1];
                    Vector2f f3 = q * p * elem.mB[2];

                    Particles[tri.i].f -= f1 / 3.0f;
                    Particles[tri.j].f -= f2 / 3.0f;
                    Particles[tri.k].f -= f3 / 3.0f;
                }
                else
                {
                    //This was the code used when fracturing was disabled
                    //in the original. It seems very unstable for me. maybe
                    //a bug or precision issue. Not used atm.

                    Matrix2x2f f = CalcDeformation(x, elem.mInvDm);

                    // elastic forces
                    Matrix2x2f e = CalcGreenStrainTensor(f);
                    Matrix2x2f s = CalcStressTensor(e, LameLambda, LameMu);

                    // damping forces
                    Matrix2x2f dfdt = CalcDeformation(v, elem.mInvDm);
                    Matrix2x2f dedt = CalcGreenStrainTensorDt(f, dfdt);
                    Matrix2x2f dsdt = CalcStressTensor(dedt, Damping, Damping);

                    Matrix2x2f p = s + dsdt;

                    float e1, e2;
                    Decomposition2x2f.EigenDecomposition(p, out e1, out e2);
                    float me = Mathf.Max(e1, e2);

                    Matrix2x2f finv = f.Transpose.Inverse;

                    Vector2f f1 = p * (finv * elem.mB[0]);
                    Vector2f f2 = p * (finv * elem.mB[1]);
                    Vector2f f3 = p * (finv * elem.mB[2]);

                    Particles[tri.i].f -= f1 / 3.0f;
                    Particles[tri.j].f -= f2 / 3.0f;
                    Particles[tri.k].f -= f3 / 3.0f;

                    Particles[tri.i].max += me / 3.0f;
                    Particles[tri.j].max += me / 3.0f;
                    Particles[tri.k].max += me / 3.0f;
                }
            }
        }
Пример #27
0
        /// <summary>
        /// calculate isotropic Hookean stress tensor, lambda and mu are the Lame parameters
        /// </summary>
        private Matrix2x2f CalcStressTensor(Matrix2x2f e, float lambda, float mu)
        {
            Matrix2x2f s = Matrix2x2f.Identity * e.Trace * lambda + e * mu * 2.0f;

            return(s);
        }
Пример #28
0
        /// <summary>
        /// calculate time derivative of Cauchy's strain tensor
        /// </summary>
        private Matrix2x2f CalcCauchyStrainTensorDt(Matrix2x2f dfdt)
        {
            Matrix2x2f e = (dfdt + dfdt.Transpose) * 0.5f;

            return(e);
        }
Пример #29
0
        /// <summary>
        /// calculate Cauchy's linear strain tensor
        /// </summary>
        private Matrix2x2f CalcCauchyStrainTensor(Matrix2x2f f)
        {
            Matrix2x2f e = (f + f.Transpose) * 0.5f - Matrix2x2f.Identity;

            return(e);
        }
Пример #30
0
        /// <summary>
        /// calculate time derivative of Green's strain
        /// </summary>
        private Matrix2x2f CalcGreenStrainTensorDt(Matrix2x2f f, Matrix2x2f dfdt)
        {
            Matrix2x2f e = (f * dfdt.Transpose + dfdt * f.Transpose) * 0.5f;

            return(e);
        }