您的位置:首页 > 移动开发 > Android开发

Android使用Catmull_Rom插值算法画光滑曲线图

2015-05-30 13:03 651 查看
一、算法核心思想

1、每次插值需要四个基础点(暂假设为A、B、C、D)。

2、根据已知的四个基础点,插值算法每次只能实现在中间两个点间画出光滑的曲线(此处就是B点和C点)。

二、工程代码

1、“Catmull_Rom插值算法”画光滑曲线的类(Catmull_Rom.java)

</pre><pre name="code" class="java">package com.example.test;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class Catmull_Rom extends View {
private final Paint mGesturePaint = new Paint();
private final Path mPath = new Path();

private ArrayList<Point> point = new ArrayList<Point>();
private ArrayList<Point> save = new ArrayList<Point>();

public Catmull_Rom(Context context) {
super(context);
}

public Catmull_Rom(Context context, AttributeSet attrs) {
super(context, attrs);
mGesturePaint.setAntiAlias(true);
mGesturePaint.setStyle(Style.STROKE);
mGesturePaint.setStrokeWidth(5);
mGesturePaint.setColor(Color.WHITE);
}

public Catmull_Rom(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
point.add(new Point(0, 0));
point.add(new Point(1, 1));
point.add(new Point(80, 100));
point.add(new Point(160, 60));
point.add(new Point(240, 120));
point.add(new Point(320, 30));
point.add(new Point(400, 200));
point.add(new Point(401, 201));

function_Catmull_Rom(point, 1000, save, mPath);
canvas.drawPath(mPath, mGesturePaint);
}

public void function_Catmull_Rom(ArrayList<Point> point, int cha, ArrayList<Point> save, Path path) {
if (point.size() < 4) {
return;
}
path.moveTo(point.get(0).x, point.get(0).y);
save.add(point.get(0));
for (int index = 1; index < point.size() - 2; index++) {
Point p0 = point.get(index - 1);
Point p1 = point.get(index);
Point p2 = point.get(index + 1);
Point p3 = point.get(index + 2);

for (int i = 1; i <= cha; i++) {
float t = i * (1.0f / cha);
float tt = t * t;
float ttt = tt * t;

Point pi = new Point(); // intermediate point
pi.x = (float) (0.5 * (2 * p1.x + (p2.x - p0.x) * t + (2 * p0.x - 5 * p1.x + 4 * p2.x - p3.x) * tt + (3 * p1.x - p0.x - 3 * p2.x + p3.x)
* ttt));
pi.y = (float) (0.5 * (2 * p1.y + (p2.y - p0.y) * t + (2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y) * tt + (3 * p1.y - p0.y - 3 * p2.y + p3.y)
* ttt));
path.lineTo(pi.x, pi.y);
save.add(pi);
pi = null;
}
}
path.lineTo(point.get(point.size() - 1).x, point.get(point.size() - 1).y);
save.add(point.get(point.size() - 1));
}
}
2、主活动(MainActivity.java)

package com.example.test;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

}
3、主布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.test.MainActivity" >

<com.example.test.Catmull_Rom
android:id="@+id/path"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</RelativeLayout>
4、坐标类(Point.java)

package com.example.test;

public class Point {
public float x;
public float y;

public Point() {
}

public Point(float x, float y) {
super();
this.x = x;
this.y = y;
}

public float getX() {
return x;
}

public void setX(float x) {
this.x = x;
}

public float getY() {
return y;
}

public void setY(float y) {
this.y = y;
}

}
三、实现效果图如下:



源代码下载地址:http://download.csdn.net/detail/ican87/8754313
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: