什麼?你不知道 DVD 是啥?呵呵,暴露年齡了。這是一個具備年代感的東西。你沒看到過說明要麼你年輕,年輕好啊。要麼你家窮,我那會兒反正是租的碟片在同窗家放,本身家買是不可能的了,一生都不可能。git
正式開始實現以前,開始簡單的建模及分析。github
總體效果就是:一個圓或者矩形在一個大的矩形(類比電視屏幕)上面運動,撞到屏幕邊緣就開始反彈,這裏類比於光的反射。直到它成功切入一個角落,那麼就中止運動。數組
轉化一下其實就是我須要在兩點連線的軌跡上面做圓或者其餘圖形,這兩點必須知足在大的矩形的任意兩邊上(能夠是相鄰的,也能夠是隔開的,單不能是同一邊)。函數
那麼對應到 Android 中就轉換成兩個問題,第一 如何經過已知點和角度和相關約束條件計算出另一個點的座標。第二 如何拿到兩點相連的軌跡。spa
針對問題一,很明確,這裏須要使用到勾股定理那些知識,或者準確的說,這裏就是須要用到「正切函數」。code
針對問題二,這裏就須要使用到 Path 和 PathMeasure 這兩個類。在 Path 中咱們能夠經過 moveTo() lineTo() 兩個方法實現兩點連線。而後調用 pathMeasure.setPath(path, false)
方式使 Path 和 PathMeasure 相關聯。接着介紹 PathMeasure 一個超級厲害的方法: pathMeasure.getPosTan(distance, positionArray, tanArray)
這個方法第一個參數指定一段長度,接着傳入兩個數組,positionArray[2] 和 tanArray[2] 。 最後positionArray 返回的就是對應 distance 後的終點座標,到這裏,終點座標問題解決。更厲害的是後面,給到你 X 和 Y 對應的正切值。那麼咱們這裏須要使用的正切值就是 tanValue = Math.abs(tanArray[1] / tanArray[0])
orm
兩個大問題解決了,在討論一些小問題,好比說運動軌跡到底有多少種? cdn
大體就是這個狀況,唉,第一次用「預覽」畫圖,你們能看明白就好。這裏具體有八種狀況的軌跡。按大類分就是四大類,分別對應各個象限的狀況。每一個象限又有上下兩種運動方向,因此就是有八大類。blog
軌跡有八種,可是要再具體的話,每一種又能夠再拆分出一種狀況。那就是上面提到的,這兩點是相鄰的或者是隔開的。get
最後直接剛上一組代碼,對應上圖的相關狀況。
private fun handUp() {
if (currentX == startX()) {// normal
val resultX = startX() + (currentY - startY()) / tanValue
val dx = resultX - endX()
if (resultX > endX()) {
Log.e("calculate", "上升 handUp:越界狀況")
val dy = tanValue * (endX() - currentX)
path.lineTo(endX(), currentY - dy)
} else {
Log.e("calculate", "上升 handUp:正常狀況")
path.lineTo(resultX, startY())
}
needRevert = dx > 0
} else if (currentX == endX()) {// normal revert
val resultX = (endY() - currentY) / tanValue
val dx = resultX - currentX
if (currentX - resultX < startX()) {
Log.e("calculate", " handUp 降低:越界狀況")
path.lineTo(startX(), rectF.height() - dx * tanValue)
needRevert = true
} else {
Log.e("calculate", " handUp 降低:正常狀況")
path.lineTo(currentX - resultX, rectF.height() - ovalY())
needRevert = false
}
} else {
Log.e(
"calculate",
" handUp 異常狀況:currentX =$currentX startX=${startX()} endx:${endX()} startX=${startX()} endx:${endX()}"
)
animator.cancel()
state = STATE_ERROR
}
}
複製代碼
最後效果就是這樣的,目前支持「圓形」和「橢圓形」
源碼地址:DVD loading by Joe