今天重点写贝塞尔二阶、三阶曲线 。 贝塞尔曲线具体原理请参考:http://baike.baidu.com/view/60154.htm?fromId=2228603
废话不说, 以下是二阶曲线,曲线上点的计算公式:
对给定的起始点(startPoint), 控制点(controlPoint) 和 终点(endPoint),计算该曲线上的点(至于计算的精度自己调整):
public static List<Point> calculatePointsConic(Point start, Point con,
Point end) {
List<Point> points = new ArrayList<Point>();
float tempX, tempY;
for (float i = 0; i <= 1; i += 0.001) {
tempX = (1 - i) * (1 - i) * start.x + 2 * i * (1 - i) * con.x + i
* i * end.x;
tempY = (1 - i) * (1 - i) * start.y + 2 * i * (1 - i) * con.y + i
* i * end.y;
Point temp = new Point(tempX, tempY);
points.add(temp);
}
return points;
}
以上就得到了二次曲线点的集合,连接每个顶点就得到了具体的二次曲线。
三阶曲线,曲线点计算公式:
相对于二阶曲线,三阶曲线多了一个控制点,曲线上点的计算,代码如下:
public static List<Point> calculatePoints(Point start, Point con1,
Point con2, Point end) {
List<Point> points = new ArrayList<Point>();
float tempX, tempY;
for (float i = 0; i <= 1; i += 0.001) {
tempX = (float) ((1 - i) * (1 - i) * (1 - i) * start.x + 3 * i
* (1 - i) * (1 - i) * con1.x + 3 * i * i * (1 - i) * con2.x + i
* i * i * end.x);
tempY = (float) ((1 - i) * (1 - i) * (1 - i) * start.y + 3 * i
* (1 - i) * (1 - i) * con1.y + 3 * i * i * (1 - i) * con2.y + i
* i * i * end.y);
Point temp = new Point(tempX, tempY);
points.add(temp);
}
return points;
}
下面的代码初始化关键点(起始点、控制点、终点):
@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("touch event has been listened ! ...");
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mPointsToDraw != null) {
mPointsToDraw.clear();
}
mStart.x = event.getX();
mStart.y = event.getY();
break;
case MotionEvent.ACTION_MOVE:
mControl1.x = mRandom.nextInt(getWidth()) * mRandom.nextFloat();
mControl2.x = mRandom.nextInt(getWidth()) * mRandom.nextFloat();
// mControl2.x = (mControl1.x +3) % getWidth() ;
mControl1.y = mRandom.nextInt(getHeight()) * mRandom.nextFloat();
// mControl2.y = mRandom.nextInt(getHeight()) * mRandom.nextFloat();
mControl2.y = (mControl1.y + 20) % getHeight();
// mPointsToDraw = calculatePoints(mStart, mControl1, mControl2,
// mEnd);
// invalidate();
break;
case MotionEvent.ACTION_UP:
mEnd.x = event.getX();
mEnd.y = event.getY();
// mPointsToDraw = calculatePoints(mStart, mControl1, mControl2,
// mEnd);
mPointsToDraw = calculatePointsConic(mStart, mControl1, mEnd);
invalidate();
break;
}
return super.onTouchEvent(event);
}
说了这么多,最想看的就是结果了,下面代码将点连接成曲线:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mPointsToDraw != null) {
canvas.drawText("Start Cordinate: ( " + mStart.x + " , " + mStart.y
+ " )", 10, 20, mPaint);
canvas.drawText("control point one Cordinate: ( " + mControl1.x
+ " , " + mControl1.y + " )", 10, 50, mPaint);
canvas.drawText("control point two Cordinate: ( " + mControl2.x
+ " , " + mControl2.y + " )", 10, 80, mPaint);
canvas.drawText("end Cordinate: ( " + mEnd.x + " , " + mEnd.y
+ " )", 10, 110, mPaint);
System.out.println("draw curve ! ...");
Point s = mPointsToDraw.get(0);
mPath.reset();
mPath.moveTo(s.x, s.y);
for (int i = 1; i < mPointsToDraw.size(); i++) {
mPath.lineTo(mPointsToDraw.get(i).x, mPointsToDraw.get(i).y);
}
canvas.drawPath(mPath, mPaint);
}
}
愿意亲身体验的童鞋呢,可以到下面的地址下载源码运行:
http://download.csdn.net/detail/sun_star1chen/5822705