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]]