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