Android(安卓)贝塞尔曲线 折线图
16lz
2021-01-24
1、贝塞尔曲线:http://baike.baidu.com/view/60154.htm,在这里理解什么是贝塞尔曲线
2、直接上图:
3、100多行代码就可以画出贝塞尔曲线,直接上代码
package com.example.bezier;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PathMeasure;import android.graphics.Paint.Style;import android.graphics.Path;import android.os.Bundle;import android.view.View;import android.view.Window;import android.view.WindowManager;public class MainActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(new BezierView(this));}}class BezierView extends View {/** * * @author liqiongwei * @param context * */public BezierView(Context context) {super(context);}protected void onDraw(Canvas canvas) {List<Float> points = new ArrayList<Float>();Paint paint = new Paint();// 添加第一个点(118.0, 294.0),points.add((float) 118.0);// X轴points.add((float) 294.0);// Y轴// 添加第二个点points.add((float) 206.0);points.add((float) 294.0);// 添加第三个点points.add((float) 294.0);points.add((float) 118.0);// 添加第四个点points.add((float) 382.0);points.add((float) 206.0);points.add((float) 470.0);points.add((float) 118.0);// 通过画折线和贝塞尔曲线可以知道,点得位置是不一样的。// 画折线for (int i = 0; i < points.size() - 2; i = i + 2) {canvas.drawLine(points.get(i), points.get(i + 1), points.get(i + 2), points.get(i + 3), paint);canvas.drawCircle(points.get(i), points.get(i + 1), 3, paint);}canvas.drawCircle(points.get(points.size() - 2), points.get(points.size() - 1), 3, paint);// 贝塞尔曲线paint.setColor(Color.BLUE);Path p = new Path();Point p1 = new Point();Point p2 = new Point();Point p3 = new Point();float xp = points.get(0);float yp = points.get(1);// 设置第一个点开始p.moveTo(xp, yp);int length = points.size();// 设置第一个控制点33%的距离float mFirstMultiplier = 0.3f;// 设置第二个控制点为66%的距离float mSecondMultiplier = 1 - mFirstMultiplier;for (int b = 0; b < length; b += 2) {int nextIndex = b + 2 < length ? b + 2 : b;int nextNextIndex = b + 4 < length ? b + 4 : nextIndex;// 设置第一个控制点calc(points, p1, b, nextIndex, mSecondMultiplier);// 设置第二个控制点p2.setX(points.get(nextIndex));p2.setY(points.get(nextIndex + 1));// 设置第二个控制点calc(points, p3, nextIndex, nextNextIndex, mFirstMultiplier);// 最后一个点就是赛贝尔曲线上的点p.cubicTo(p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY());// 画点}PathMeasure mPathMeasure; mPathMeasure = new PathMeasure(p, false);// 设置为线paint.setStyle(Style.STROKE);reSetPointWithPath(mPathMeasure, points);for (int k = 0; k < points.size()-1; k +=2) {canvas.drawCircle(points.get(k), points.get(k+1), 5, paint);}canvas.drawPath(p, paint);invalidate();}/** * 计算控制点 * @param points * @param result * @param index1 * @param index2 * @param multiplier */private void calc(List<Float> points, Point result, int index1, int index2, final float multiplier) {float p1x = points.get(index1);float p1y = points.get(index1 + 1);float p2x = points.get(index2);float p2y = points.get(index2 + 1);float diffX = p2x - p1x;float diffY = p2y - p1y;result.setX(p1x + (diffX * multiplier));result.setY(p1y + (diffY * multiplier));}/** * 重新设置点的位置,为曲线上的位置 * @param mPathMeasure * @param pointsList */public void reSetPointWithPath(PathMeasure mPathMeasure, List<Float> pointsList){ int length = (int) mPathMeasure.getLength(); int pointsLength = pointsList.size(); float[] coords = new float[2]; for (int b = 0; b < length; b++) { mPathMeasure.getPosTan(b, coords, null); double prevDiff = Double.MAX_VALUE; boolean ok = true; for (int j = 0; j < pointsLength && ok; j += 2) { double diff = Math.abs(pointsList.get(j) - coords[0]); if (diff < 1) { pointsList.set(j + 1, coords[1]); prevDiff = diff; } ok = prevDiff > diff; } }}}
4、定义点的类
package com.example.bezier;import java.io.Serializable;/** * 点的类,来源于Achartengine */public final class Point implements Serializable { private float mX; private float mY; public Point() { } public Point(float x, float y) { mX = x; mY = y; } public float getX() { return mX; } public float getY() { return mY; } public void setX(float x) { mX = x; } public void setY(float y) { mY = y; }}
5、下载地址:http://files.cnblogs.com/liqw/Bezier.zip
本文来源于:http://www.cnblogs.com/liqw/p/3631137.html
有问题,请提问,大家一起研究!
更多相关文章
- android 学习之popupWindow 在指定位置上的显示,进出样式。
- activity 之间切换添加动画效果(二)
- Android(安卓)MapView 申请apiKey
- Android(安卓)Studio和Gradle 没同步JDK、SDK、NDK所遇到的坑
- android 动态改变控件位置和大小
- android 动态改变控件的位置的方法
- Android(安卓)Wi-Fi Firmware(wcnss)修改方法(以QCOM为平台)
- 自定义Android(安卓)ListView控件:ExpandableListView
- android百度地图(二)之定位