Пример #1
0
        public void TestAbs1()
        {
            var expr = MathS.Abs(x) + 4;
            var func = expr.Compile(x);

            Assert.Equal(4, func.Call(0));
        }
Пример #2
0
        public void TestAbs3()
        {
            var expr = MathS.Abs(x) + 4;
            var func = expr.Compile(x);

            Assert.Equal(9, func.Call(new Complex(3, 4)));
        }
Пример #3
0
 public Vector3 ToVector3()
 {
     if (MathS.Abs(w) <= Threshold)
     {
         return(new Vector3(x, y, z));
     }
     else
     {
         return(new Vector3(x / w, y / w, z / w));
     }
 }
Пример #4
0
 private IVertexOutputData[] ClipPolygon(IVertexOutputData[] polygon)
 {
     for (int planeIndex = 0; planeIndex < 6; planeIndex++)
     {
         List <IVertexOutputData> vdatas = new List <IVertexOutputData>();
         int vi   = planeIndex / 2;
         int sign = planeIndex % 2 == 0 ? 1 : -1;
         for (int pointIndex = 0; pointIndex < polygon.Length; pointIndex++)
         {
             int index0           = pointIndex;
             int index1           = pointIndex == polygon.Length - 1 ? 0 : pointIndex + 1;
             IVertexOutputData v0 = polygon[index0];
             IVertexOutputData v1 = polygon[index1];
             Vector4           p0 = v0.clip;
             Vector4           p1 = v1.clip;
             Vector3           n0 = v0.viewNormal;
             Vector3           n1 = v1.viewNormal;
             float             d0 = (p0[vi] + p0.w * sign) * p0.w;
             float             d1 = (p1[vi] + p1.w * sign) * p1.w;
             float             ds = d0 * d1;
             if (ds < 0)
             {
                 // 边与裁剪面相交
                 float   u = d0 / (d0 - d1);
                 Vector4 p = p0 + (p1 - p0) * u;
                 Vector3 n = n0 + (n1 - n0) * u;
                 if (sign * d0 > 0)
                 {
                     vdatas.Add(v0);
                 }
                 IVertexOutputData data = new VertexOutputData();
                 data.clip       = p;
                 data.viewNormal = n;
                 vdatas.Add(data);
             }
             else if (MathS.Abs(d0) < Threshold)
             {
                 // p0点在裁剪面上
                 vdatas.Add(v0);
             }
             else if (sign * d0 > 0 && sign * d1 >= 0)
             {
                 // 边完全位于裁剪面之内
                 vdatas.Add(v0);
             }
         }
         polygon = vdatas.ToArray();
     }
     return(polygon);
 }
Пример #5
0
    public IVertexOutputData Triangle(IVertexOutputData[] clips, Vector2[] screens, int[] pixel)
    {
        Vector2 center = new Vector2(pixel[0], pixel[1]);
        float   a      = MathS.Abs(Vector2.Cross(screens[1] - screens[0], screens[2] - screens[0]) * 0.5f);
        // 重心法求插值系数
        float a0 = MathS.Abs(Vector2.Cross(screens[1] - screens[0], center - screens[0]) * 0.5f) / a;
        float a1 = MathS.Abs(Vector2.Cross(screens[2] - screens[1], center - screens[1]) * 0.5f) / a;
        float a2 = MathS.Abs(Vector2.Cross(screens[0] - screens[2], center - screens[2]) * 0.5f) / a;
        // 插值
        IVertexOutputData lerp = new VertexOutputData();

        lerp.clip       = a0 * clips[0].clip + a1 * clips[1].clip + a2 * clips[2].clip;
        lerp.viewNormal = a0 * clips[0].viewNormal + a1 * clips[1].viewNormal + a2 * clips[2].viewNormal;
        return(lerp);
    }
Пример #6
0
    public Vector3 Perpendicular()
    {
        float ax = MathS.Abs(x);
        float ay = MathS.Abs(y);
        float az = MathS.Abs(z);

        if (ax < ay && ax < az)
        {
            return(new Vector3(0, -z, y));
        }
        else if (ay < ax && ay < az)
        {
            return(new Vector3(-z, 0, x));
        }
        else
        {
            return(new Vector3(-y, x, 0));
        }
    }
Пример #7
0
    /// <summary>
    /// 旋转单位向量From到另外一个单位向量To
    /// </summary>
    /// <param name="from">单位向量</param>
    /// <param name="to">单位向量</param>
    /// <returns>单位四元数</returns>
    public static Quaternion FromTo(Vector3 from, Vector3 to)
    {
        Quaternion uq    = Quaternion.identity;
        float      squar = 2 * (1 + Vector3.Dot(from, to));

        if (MathS.Abs(squar) <= Threshold)
        {
            Vector3 perp = from.Perpendicular().normalized;
            uq = new Quaternion(perp.x, perp.y, perp.z, 0);
        }
        else
        {
            float   root = MathS.Sqrt(squar);
            Vector3 imag = from.Cross(to) / root;
            float   real = root * 0.5f;
            uq = new Quaternion(imag.x, imag.y, imag.z, real);
        }
        return(uq);
    }
Пример #8
0
    /// <summary>
    /// 旋转轴和旋转角(单位四元数有效)
    /// </summary>
    /// <param name="angle"></param>
    /// <param name="axisNormal"></param>
    public void ToAngleAxis(out float angle, out Vector3 axisNormal)
    {
        Vector3 axis = new Vector3(
            MathS.Abs(x) <= Threshold ? 0f : x,
            MathS.Abs(y) <= Threshold ? 0f : y,
            MathS.Abs(z) <= Threshold ? 0f : z
            );

        if (axis == Vector3.zero)
        {
            angle      = 0;
            axisNormal = Vector3.zero;
        }
        else
        {
            float length = axis.magnitude;
            angle      = MathS.Atan2(length, w) * 2 * MathS.RadToDeg;
            axisNormal = axis / length;
        }
    }
Пример #9
0
    /// <summary>
    /// 欧拉角(单位四元数有效)
    /// </summary>
    /// <returns></returns>
    public Vector3 ToEulers()
    {
        Vector3 euler = Vector3.zero;
        Matrix  m     = ToMatrix();

        if (MathS.Abs(m[1, 0]) <= Threshold &&
            MathS.Abs(m[1, 1]) <= Threshold)
        {
            euler.x = m[1, 2] <= 0 ? 90 : -90;
            euler.y = 0;
            euler.z = MathS.Atan2(-m[0, 1], m[0, 0]) * MathS.RadToDeg;
        }
        else
        {
            euler.x = MathS.Asin(-m[1, 2]);
            euler.y = MathS.Atan2(m[0, 2], m[2, 2]);
            euler.z = MathS.Atan2(m[1, 0], m[1, 1]);
            euler  *= MathS.RadToDeg;
        }
        return(euler);
    }
Пример #10
0
 [Fact] public void Abs()
 => Test(@"\left|x\right|", MathS.Abs(x));
Пример #11
0
 public float Distance(Vector3 point)
 {
     return(MathS.Abs(point.Dot(mNormal) - md));
 }