查看完整版本 : Flash 的shape tweening

Susan﹏汪汪 2017-3-6 11:22

[code]func BezierTweening(start: Bezier<Point>, end: Bezier<Point>, _ t: Double) -> Bezier<Point> {
   
    var start = start
    var end = end
   
    let degree = max(start.degree, end.degree)
   
    while start.degree != degree {
        start = start.elevated()
    }
    while end.degree != degree {
        end = end.elevated()
    }
   
    let start_first = start.first!
    let start_last = start.last!
    let end_first = end.first!
    let end_last = end.last!
    let d1 = start_last - start_first
    let d2 = end_last - end_first
   
    let transform1 = SDTransform.Translate(x: -start_first.x, y: -start_first.y) * SDTransform.Scale(1 / d1.magnitude) * SDTransform.Rotate(-d1.phase)
    let s = Bezier(start.map { $0 * transform1 })
   
    let transform2 = SDTransform.Translate(x: -end_first.x, y: -end_first.y) * SDTransform.Scale(1 / d2.magnitude) * SDTransform.Rotate(-d2.phase)
    let e = Bezier(end.map { $0 * transform2 })
   
    let m = (1 - t) * s + t * e
   
    let m_start = (1 - t) * start_first + t * end_first
    let m_end = (1 - t) * start_last + t * end_last
    let m_d = m_end - m_start
   
    let transform3 = SDTransform.Rotate(m_d.phase) * SDTransform.Scale(m_d.magnitude) * SDTransform.Translate(x: m_start.x, y: m_start.y)
    return Bezier(m.map { $0 * transform3 })
}[/code]

Susan﹏汪汪 2017-3-6 11:53

正方形轉左90度
[attach]6582415[/attach]

簡化[code]public func BezierTweening(start: [Point], end: [Point], _ t: Double) -> [Point] {
   
    let start_start = start.first!
    let start_end = start.last!
    let end_start = end.first!
    let end_end = end.last!
    let d1 = start_end - start_start
    let d2 = end_end - end_start
   
    let transform1 = SDTransform.Translate(x: -start_start.x, y: -start_start.y) * SDTransform.Scale(1 / d1.magnitude) * SDTransform.Rotate(-d1.phase)
    let s = Bezier(start.map { $0 * transform1 })
   
    let transform2 = SDTransform.Translate(x: -end_start.x, y: -end_start.y) * SDTransform.Scale(1 / d2.magnitude) * SDTransform.Rotate(-d2.phase)
    let e = Bezier(end.map { $0 * transform2 })
   
    let m = (1 - t) * s + t * e
   
    let m_start = (1 - t) * start_start + t * end_start
    let m_end = (1 - t) * start_end + t * end_end
    let m_d = m_end - m_start
   
    let transform3 = SDTransform.Rotate(m_d.phase) * SDTransform.Scale(m_d.magnitude) * SDTransform.Translate(x: m_start.x, y: m_start.y)
    return m.map { $0 * transform3 }
}[/code]

煙民母親生賤種

*** 作者被禁止或刪除 內容自動屏蔽 ***

mack0817 2017-3-6 23:14

嘩,這很強大喔,很難想像這些功能,我以為Adobe工程師先可以做到。

Susan﹏汪汪 2017-3-6 23:54

呢個完全冇難度

之前寫過Coons patch
https://www.discuss.com.hk/viewthread.php?tid=26457041
https://en.wikipedia.org/wiki/Coons_patch

其中個核心思想係對curves 本身去做linear interpolation
L = (1 - t) * B_1 + t * B_2
B_1 和 B_2係兩條bezier curves

不過寫呢個會發現
直接對兩條curve做interpolation 會出問題
所以段code有scale同rotate就係解決個問題
寫過一次就會知道

[[i] 本帖最後由 Susan﹏汪汪 於 2017-3-6 11:57 PM [url=http://www.discuss.com.hk/iphone][img=100,23]http://i.discuss.com.hk/d/images/r10/iphoneD.jpg [/img][/url] 編輯 [/i]]
頁: [1]
查看完整版本: Flash 的shape tweening