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

一、算法核心思想

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;
  }

}

三、实现效果图如下:

时间: 2024-10-01 08:08:13

Android使用Catmull_Rom插值算法画光滑曲线图的相关文章

使用AChartEngine画动态曲线图

AChartEngine是一个开源的Android图表库,可以用来画折线图.平滑折线图.饼图.直方图等等.使用简单,功能强大. AChartEngine官网:http://www.achartengine.org/ AChartEngine库文件:http://repository-achartengine.forge.cloudbees.com/snapshot/org/achartengine/achartengine/1.2.0/ 库文件直接导入就可以使用了. 网上介绍AChartEngi

Android通过用代码画虚线椭圆边框背景来学习一下shape的用法

在Android程序开发中,我们经常会去用到Shape这个东西去定义各种各样的形状,shape可以绘制矩形环形以及椭圆,所以只需要用椭圆即可,在使用的时候将控件比如imageview或textview的高宽设置成一样就是正圆,solid表示远的填充色,stroke则代表远的边框线,所以两者结合可以实现带边缘的圆,当然也可以直接加上size控制高宽.那么我首先带你们了解一下Shape下有哪些标签,并且都代表什么意思: shape属性: rectangle:矩形 oval:椭圆 line:线,需要

android tv 全屏幕垂直画

它们的定义view 采纳canvas双缓冲方式,它可以减少呈现时间.提高性能. StaggeredView.java 源码例如以下: package com.xxx.demo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; imp

Android 使用shape来画线

注意:Android3.0以上系统开始支持硬件加速特性hardwareAccelerated,默认是启用的.当你的某个activity用到了“虚线”效果的时候,必须要设置AndroidManifest文件中那个activity的硬件加速属性为:Android:hardwareAccelerated="false",否则是不会显示”虚线“效果的.具体原因也不是很清楚. 利用shape来画line,很简单,我很快就能写出一个line类型的shape文件,然后设置到一个view的backgr

Android 开发 -------- 自定义View 画 五子棋

自定义View  实现 五子棋 配图: 代码: package com.example.fiveson; import java.util.LinkedList; import java.util.List; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util

Android开发经验之获取画在画布上的字符串长度、宽度(所占像素宽度)

Android中获取字符串长度.宽度(所占像素宽度) 计算出当前绘制出来的字符串有多宽,可以这么来! 方法1: Paint paint = new Paint(); Rect rect = new Rect(); //返回包围整个字符串的最小的一个Rect区域 paint.getTextBounds(text, 0, 1, rect); strwid = rect.width(); strhei = rect.height(); 方法2: //直接返回参数字符串所占用的宽度 strWidth =

(五十三) android中用xml文件画圆

1.draw_cirle.xml的代码如下所示: <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <solid android:color="#999999"/> <size android:width="5dp" android:height="5dp&qu

android简单定位和画地图

在讲解代码前,首先配置AndroidManifest.xml 以下权限貌似是缺一不可哦: <!-- 访问网络,网络定位需要上网 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 这个权限用于访问GPS定位 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOC

ZGrapher 画函数曲线图的工具

可以下载个绿色版,我下载的是 ZGrapher 1.4 绿色版.下面先看下图出来的图: 然后可以在“file"->"Save as Picture ..." -> 然后输出生成的图片大小,比如:600x400,保存即可. zgrapher 支持的函数常用的都有,如:sin(x).cos(x).ln(x).lg(x).exp(x).x^2.sqrt(x)……其中 lg(x) 表示 log10(x),exp(x) 表示 ex,可以看ZGrapher.chm的说明.