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

来源:互联网 发布:淘宝薅羊毛是怎么弄的 编辑:程序博客网 时间:2024/05/22 17:03

一、算法核心思想
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


1 0
原创粉丝点击