コード例 #1
0
    /// <summary>
    /// 判断是否包围了原点
    /// <para>如果没有包含,且点数超过2时,只保留连线离原点最近的两个点</para>
    /// </summary>
    /// <returns></returns>
    public bool DoSimplex2D()
    {
        bool certain = false;

        if (count == 1 ||
            count == 2)
        {
            certain = false;
        }
        else if (count == 3)
        {
            LVector2 p02 = LGeometryUtil2D.GetPerpendicular2D(vertics[0].p, vertics[2].p, vertics[1].p);
            if (LVector2.Dot(-vertics[0].p, p02) >= 0)
            {
                LVector2 p12 = LGeometryUtil2D.GetPerpendicular2D(vertics[1].p, vertics[2].p, vertics[0].p);
                if (LVector2.Dot(-vertics[1].p, p12) >= 0)
                {
                    certain = true;
                }
                else
                {
                    RemoveIndex(0);
                }
            }
            else
            {
                RemoveIndex(1);
            }
        }
        return(certain);
    }
コード例 #2
0
ファイル: EPAFace2D.cs プロジェクト: SylarLi/LPhysics
    public LFloat sqrMagnitude;      // 原点到直线的距离的平方

    public EPAFace2D(SimplexPoint2D sp1, SimplexPoint2D sp2)
    {
        this.sp1 = sp1;
        this.sp2 = sp2;
        // 这里使用计算直线交点的方向求得原点到直线的最短向量
        LVector2 D = -LGeometryUtil2D.GetPerpendicular2D(sp1.p, sp2.p, LVector2.zero);

        if (sp2.p.x == sp1.p.x)
        {
            LFloat x = sp1.p.x;
            this.direction    = new LVector2(x, 0);
            this.sqrMagnitude = x * x;
        }
        else
        {
            if (D.x == 0)
            {
                LFloat y = sp1.p.y;
                this.direction    = new LVector2(0, y);
                this.sqrMagnitude = y * y;
            }
            else
            {
                LFloat k1 = (sp2.p.y - sp1.p.y) / (sp2.p.x - sp1.p.x);
                LFloat b1 = (sp2.p.y * sp1.p.x - sp2.p.x * sp1.p.y) / (sp1.p.x - sp2.p.x);
                LFloat k2 = D.y / D.x;
                LFloat b2 = 0;
                LFloat y  = (b1 * k2 - b2 * k1) / (k2 - k1);
                LFloat x  = y / k2;
                this.direction    = new LVector2(x, y);
                this.sqrMagnitude = x * x + y * y;
            }
        }
    }
コード例 #3
0
ファイル: LBoxCollider2D.cs プロジェクト: SylarLi/LPhysics
 internal override void PrepareForCollision()
 {
     base.PrepareForCollision();
     CalculateLocalVertics();
     for (int i = mLocalVertics.Length - 1; i >= 0; i--)
     {
         mVertics[i] = transform.TransformPoint(mLocalVertics[i]);
     }
     mBounds = LGeometryUtil2D.CalcBounds(mVertics);
 }
コード例 #4
0
    /// <summary>
    /// 返回一个离原点最近的一个点到原点方向的向量
    /// <para>注:如果vertics中只有一个点,直接计算返回</para>
    /// <para>注:如果vertics中有两个点,向量为两点连线的垂线(指向原点的方向)</para>
    /// </summary>
    /// <returns></returns>
    public LVector2 FindClosestPointToOriginDirection()
    {
        LVector2 dir = LVector2.up;

        if (count == 1)
        {
            dir = -vertics[0].p;
        }
        else if (count == 2)
        {
            dir = LGeometryUtil2D.GetPerpendicular2D(vertics[0].p, vertics[1].p, LVector2.zero);
        }
        return(dir);
    }
コード例 #5
0
    private LContactConstraint2D ContactConstraintGenerate(LPhysicsObject2D objA, LPhysicsObject2D objB)
    {
        LContactConstraint2D constraint = null;
        Vector2 contactPointsA          = LGeometryUtil2D.CalcBarycentric(closestFace.sp1.a, closestFace.sp2.a);
        Vector2 contactPointsB          = LGeometryUtil2D.CalcBarycentric(closestFace.sp1.b, closestFace.sp2.b);

        if (closestFace.sqrMagnitude > LPhysicsStatic2D.DistanceSqrtThreshold)
        {
            float   penetration = Mathf.Sqrt(closestFace.sqrMagnitude);
            Vector2 normal      = closestFace.direction / penetration;
            if (objA.rigidBody != null ||
                objB.rigidBody != null)
            {
                constraint             = new LContactConstraint2D(objA, objB);
                constraint.anchorA     = contactPointsA;
                constraint.anchorB     = contactPointsB;
                constraint.normal      = normal;
                constraint.penetration = penetration;
            }
        }
        return(constraint);
    }