本次閱讀大概需要5分鐘
先看效果
簡單說明一下(對(duì)名稱不清楚的都能在下文中找到,不要著急)
1.本案例適用于類似給定每天的銷售額,畫出當(dāng)月的銷售曲線
2.本曲線的特點(diǎn)是曲線任意處都是光滑的,數(shù)據(jù)點(diǎn)之間的曲線任意值都不能大于數(shù)據(jù)點(diǎn)值同時(shí)也不存在極值點(diǎn)(要么是上升曲線要么下降曲線,不可以是又上升又下降)
3.我們實(shí)現(xiàn)平滑需求使用的核心功能是三次貝塞爾曲線,我們要解決的核心問題是找到三次貝塞爾曲線的兩個(gè)控制點(diǎn)
4.貝塞爾曲線本身是平滑的(這個(gè)不做證明)
mPath.moveTo(currentPointX,currentPointY);
mPath.cubicTo(firstControlPointX, firstControlPointY, secondControlPointX, secondControlPointY, nextPointX, nextPointY);
數(shù)據(jù)點(diǎn)P0(currentPointX,currentPointY)和P1(nextPointX,nextPointY)是給定的,我們的核心是如何找到firstControlPoint(firstControlPointX, firstControlPointY,)和secondControlPoint (secondControlPointX, secondControlPointY) 這兩個(gè)點(diǎn)不是唯一的,準(zhǔn)確的說有無數(shù)多個(gè),我們只要找到其中一組就可以。
如果firstControlPoint 和secondControlPoint 可以滿足以下兩個(gè)條件就可以實(shí)現(xiàn)我們的目標(biāo)了
- 生成的曲線是光滑的那么就必須滿足C2 P2 C3在同一條直線上, C4 P3 C5在同一條直線上。
-
C1 C2 在P1與P2的矩形范圍之間 (可以等于),C3 C4在P2 P3的矩形范圍之間并且C2 Y方向距離P2要小于等于C1到P2的距離
數(shù)據(jù)點(diǎn)與控制點(diǎn)位置關(guān)系圖 圖1
一. 關(guān)于貝塞爾曲線(如果清楚可以跳過)
1. 什么是貝塞爾曲線##
線性貝塞爾曲線:
二次貝塞爾曲線:
三次貝塞爾曲線:
以下證明過程解釋為什么我們要使用三次貝塞爾曲線
定理:設(shè)三次貝塞爾曲線的四個(gè)點(diǎn)為P0,P1,P2,P3(其中P0和P3稱為端點(diǎn),P1和P2稱為控制點(diǎn)),則P0和P1的連線是P0的切線,P3和P2的連線是P3的切線。
我們之前說了貝塞爾曲線是光滑的,那如果希望我們所有的位置都是光滑的,那么連接點(diǎn)處必須也要光滑,如下圖 我們剛剛證明了,使用三次貝塞爾曲線C2與P2的連線與P1 C1 C2 P2生成的曲線是相切的,同樣三次貝塞爾曲線P2與C3的連線與P2 C3 C4 P3生成的曲線也是相切的,(當(dāng)曲線上每一點(diǎn)處都具有切線,且切線隨切點(diǎn)的移動(dòng)而連續(xù)轉(zhuǎn)動(dòng),這樣的曲線成為光滑曲線。如果C2與P2連成的線C2P2同P2與C3連成的線P2C3是同一條直線那么P1 P2之間的曲線和P2 P3之間的曲線在P2點(diǎn)是光滑的)這就是為什么要使用三次貝塞爾曲線的理論基礎(chǔ) 如果生成的曲線是光滑的那么就必須滿足C2 P2 C3在同一條直線上, C4 P3 C5在同一條直線上。
如果C1 和C2在我們的P1和P2之間那么生成的曲線就不會(huì)超過給數(shù)據(jù)點(diǎn)這個(gè)通過三次貝塞爾曲線的圖就可以看出,當(dāng)然如果C1,C2超過了P1和P2那生成的曲線可能也會(huì)在P1和P2之間
二. 關(guān)于代碼部分
mPath.moveTo(P0.x,P0.y);
mPath.cubicTo(firstControlPointX, firstControlPointY, secondControlPointX, secondControlPointY, P3.x, P3.y);
其中P1(firstControlPointX, firstControlPointY) P2(secondControlPointX, secondControlPointY)是控制點(diǎn)我們生成 不是數(shù)據(jù)點(diǎn)請(qǐng)注意。
代碼地址
https://github.com/jiahengcen/SmoothPoint