求二次、三次贝塞尔曲线的某个时间的位置及切线方向

Public Module BezierHelper
    ''' <summary>
    ''' 获得二次贝塞尔曲线在某个时刻的位置
    ''' B(t) = PA(1-t)^2+ 2PBt(1-t) + PCt^2
    ''' </summary>
    ''' <param name="PA">起始点</param>
    ''' <param name="bs">二次贝塞尔曲线</param>
    ''' <param name="t">时间t 0~1</param>
    Public Function GetPosition(PA As Point, bs As QuadraticBezierSegment, t As Single) As Point
        Dim pr As Point
        pr.X = PA.X * (1 - t) ^ 2 + 2 * bs.Point1.X * t * (1 - t) + bs.Point2.X * t ^ 2
        pr.Y = PA.Y * (1 - t) ^ 2 + 2 * bs.Point1.Y * t * (1 - t) + bs.Point2.Y * t ^ 2
        Return pr
    End Function

    ''' <summary>
    ''' 获得二次贝塞尔曲线在某个时刻的切线方向
    ''' </summary>
    ''' <param name ="PA">起始点</param>
    ''' <param name="bs">二次贝塞尔曲线</param>
    ''' <param name="t">时间t 0~1</param>
    ''' <returns></returns>
    Public Function GetTangentAngle(PA As Point, bs As QuadraticBezierSegment, t As Single) As Single
        Dim dr As Point
        REM 变量X受自变量时间t 在X方向的变化率
        dr.X = PA.X * 2 * (1 - t) * (-1) +
            2 * bs.Point1.X * ((1 - t) + (-1) * t) +
            bs.Point2.X * 2 * t
        dr.Y = PA.Y * 2 * (1 - t) * -1 +
            2 * bs.Point1.Y * ((1 - t) + (-1) * t) +
            bs.Point2.Y * 2 * t
        Return Math.Atan2(dr.Y, dr.X)
    End Function

    ''' <summary>
    ''' 获得三次贝塞尔曲线在某个时刻的位置
    ''' B(t) = PA(1-t)^3 + 3PBt(1-t)^2 + 3PCt^2(1-t) + PDt^3
    ''' </summary>
    ''' <param name="PA">起始点</param>
    ''' <param name="bs">三次贝塞尔曲线</param>
    ''' <param name="t">时间t 0~1</param>
    Public Function GetPosition(PA As Point, bs As BezierSegment, t As Single) As Point
        Dim pr As Point
        pr.X = PA.X * (1 - t) ^ 3 + 3 * bs.Point1.X * t * (1 - t) ^ 2 _
        + 3 * bs.Point2.X * t ^ 2 * (1 - t) + bs.Point3.X * t ^ 3
        pr.Y = PA.Y * (1 - t) ^ 3 + 3 * bs.Point1.Y * t * (1 - t) ^ 2 _
        + 3 * bs.Point2.Y * t ^ 2 * (1 - t) + bs.Point3.Y * t ^ 3
        Return pr
    End Function

    ''' <summary>
    ''' 获得三次贝塞尔曲线在某个时刻的切线方向
    ''' </summary>
    ''' <param name ="PA">起始点</param>
    ''' <param name="bs">三次贝塞尔曲线</param>
    ''' <param name="t">时间t 0~1</param>
    ''' <returns></returns>
    Public Function GetTangentAngle(PA As Point, bs As BezierSegment, t As Single) As Single
        Dim dr As Point
        REM 变量X受自变量时间t 在X方向的变化率
        dr.X = PA.X * 3 * (1 - t) ^ 2 * (-1) +
            3 * bs.Point1.X * ((1 - t) ^ 2 + t * 2 * (1 - t) * (-1)) +
            3 * bs.Point2.X * (2 * t * (1 - t) + t ^ 2 * (-1)) +
            bs.Point3.X * 3 * t ^ 2

        dr.Y = PA.Y * 3 * (1 - t) ^ 2 * (-1) +
            3 * bs.Point1.Y * ((1 - t) ^ 2 + t * 2 * (1 - t) * (-1)) +
            3 * bs.Point2.Y * (2 * t * (1 - t) + t ^ 2 * (-1)) +
            bs.Point3.Y * 3 * t ^ 2

        Dim angle As Single = Math.Atan2(dr.Y, dr.X) * 180 / 3.14
        'Console.Clear()
        'Console.WriteLine(dr.X.ToString("f2") + "  " + dr.Y.ToString("f2") + " " + angle.ToString("f2"))
        Return angle
    End Function
End Module
阅读更多
个人分类: 经验
上一篇float的实际存储和计算方法
下一篇Unity利用 UI的Mask实现对精灵Sprite的遮挡
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭