zoukankan      html  css  js  c++  java
  • Android 贝塞尔曲线 折线图

    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 {
    	@Override
    	public 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

    有问题,请提问,大家一起研究!

  • 相关阅读:
    webrtc学习资源
    HTML5视音频标签参考
    ffmpeg 翻译文档
    音频编码器
    opensource mcu
    无法解析的外部符号 "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ)"
    AAC头部格式
    C++11系列-什么是C++11
    Neo4J空间数据存储
    Neo4j 3.0 存储过程
  • 原文地址:https://www.cnblogs.com/liqw/p/3631137.html
Copyright © 2011-2022 走看看