Example #1
0
    /// <summary>
    /// 通过距离起点的距离,获取线上的点的坐标、斜率、圆心到坐标的单位向量(垂直于斜率)
    /// </summary>
    public void GetSampleAtDistance(float distance, out Vector3 position, out Vector3 tangent, out Vector3 emit)
    {
        LinkedListNode <PBCircleNode> listNode = nodes.First;
        PBCircleNode startNode = null;
        PBCircleNode endNode   = null;

        while (listNode != null)
        {
            if (distance < listNode.Value.distance)
            {
                startNode = listNode.Previous.Value;
                endNode   = listNode.Value;
                break;
            }
            listNode = listNode.Next;
        }

        if (startNode == null)
        {
            throw new ArgumentException(string.Format("Distance must be less than curve length. Curve length: {0}, distance: {1}",
                                                      nodes.Last.Value.distance, distance));
        }

        float t = (distance - startNode.distance) / (endNode.distance - startNode.distance);

        if (startNode.ConnectLine(endNode))
        {
            //直线
            position = Vector3.Lerp(startNode.position, endNode.position, t);
            tangent  = startNode.tangent;
            emit     = (startNode.position - startNode.circle.center).normalized;
        }
        else
        {
            //圆弧
            PBCircle circle = startNode.circle;
            float    angle  = startNode.angle + t * startNode.deltaAngle(endNode);
            Vector3  r      = Quaternion.AngleAxis(angle, circle.forward) * circle.up;
            r.Normalize();
            position = circle.center + r * circle.radius;

            tangent = Quaternion.AngleAxis(angle, circle.forward) * (-circle.right);

            emit = r;
        }
    }
    public static LinkedList <PBCircleNode> Build(PBCircle[] circles, PBCircleCurveType type)
    {
        LinkedList <PBCircleNode> nodes = null;

        switch (type)
        {
        case PBCircleCurveType.OneCircle:
            nodes = BuildForOne(circles);
            break;

        case PBCircleCurveType.Line:
            nodes = BuildForLine(circles);
            break;

        case PBCircleCurveType.Enclosed:
            nodes = BuildForEnclosed(circles);
            break;
        }

        //compute distance for nodes
        LinkedListNode <PBCircleNode> listNode = nodes.First;

        listNode.Value.distance = 0;
        listNode = listNode.Next;
        while (listNode != null)
        {
            PBCircleNode node    = listNode.Value;
            PBCircleNode preNode = listNode.Previous.Value;
            if (node.ConnectLine(preNode))
            {
                //直线
                node.distance = preNode.distance + Vector3.Distance(node.position, preNode.position);
                //Debug.Log(">>>>>>>1 distance: " + node.distance);
            }
            else
            {
                //圆弧
                float radius = node.circle.radius;
                node.distance = preNode.distance + preNode.deltaAngle(node) * Mathf.Deg2Rad * radius;
                //Debug.Log(">>>>>>>2 distance: " + node.distance);
            }
            listNode = listNode.Next;
        }
        return(nodes);
    }