2013-03-11 188 views
2

我想创建更多平滑曲线,而不仅是线条角度。这是图片我此刻是如何得出:绘制平滑曲线

enter image description here

这里是我的代码:

case FREEHAND: 
    float[] pts; 
    float[] ptk; 
    ptk = new float[2]; 
    imageMatrix.invert(inv);    
    if (mCurrentShape == null) {     
     mCurrentShape = new Line(); 
     pts = new float[2]; 
     ((Line) mCurrentShape).setBegin(mDownPoint); 
     pts[0] = (float)((Line) mCurrentShape).getBegin().getX(); 
     pts[1] = (float)((Line) mCurrentShape).getBegin().getY(); 
     inv.mapPoints(pts); 
     ((Line) mCurrentShape).getPath().moveTo(pts[0], pts[1]); 
    } 
    ptk[0] = (float)currentPoint.getX(); 
    ptk[1] = (float)currentPoint.getY(); 
    inv.mapPoints(ptk); 
    ((Line) mCurrentShape).getPath().lineTo(ptk[0], ptk[1]); 
    break; 

写意代码:

package aa.bb.cc; 
import java.util.ArrayList; 
import android.graphics.Path; 

public class FreeHand extends Shape{ 
    private ArrayList<Path>_graphics; 

    public FreeHand(){ 
     super(); 
     _graphics = new ArrayList<Path>(); 
    } 

    public ArrayList<Path> getGraphicsPath(){ 
     return _graphics; 
    } 
} 
+1

看看这个:http://corner.squareup.com/2012/07/smoother-signatures.html它不是一个完整的解决方案,但它给你一个你可以做什么的想法。 – 2013-03-11 12:00:00

+0

这篇关于贝塞尔曲线的文章可能很有用: http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/ – stan0 2013-03-11 13:47:13

回答

-1

我有一个代码,使用二次贝塞尔线平滑点。这真的很好。它也非常有效。使用以下类构建平滑路径。每次有新点时,请使用addPoint(x, y)添加它。完成后,您可以拨打constructPath()以获取平滑路径。与评论中的解决方案比较,比如“corner.squareup.com/2012/07/smoother-signatures.html”,我的解决方案避免了原始路径非常尖锐的角落处的人为现象。

public class BezierCurveConstructor { 
Path path; 

PointF previousPoint; 
int pointCounter = 0; 

public BezierCurveConstructor() { 
    reset(); 
} 


/** 
* reset the path 
*/ 
public void reset() { 
    path = new Path(); 
    pointCounter = 0; 
} 


public void addPoint(float x, float y) { 

    pointCounter ++; 
    if (pointCounter == 1) { 
     path.moveTo(x, y); 
     previousPoint = new PointF(x, y); 
     return; 
    } 


    PointF mid = new PointF((x + previousPoint.x)/2.0f, (y + previousPoint.y)/2.0f); 

    if (pointCounter < 3) { 
     path.lineTo(mid.x, mid.y); 
    } else { 
     path.quadTo(previousPoint.x, previousPoint.y, mid.x, mid.y); 
    } 
    previousPoint = new PointF(x, y); 
} 

/** 
* construct path by points 
* 
* @return 
*/ 
public Path constructPath() { 
    return path; 
} 

}

此路径包含二次贝塞尔曲线经过前点的所有中间点和你接触的下一个点去的名单。请注意,此路径具有不变的二阶导数,但一阶导数在胶粘点处匹配。我们可以证明为什么如此通过下面的推导:

Denote the list of points as p_0, p_1, ... p_n, (these can be points in R^n) let c_i = (pi+p_{i_1})/2 as the middle point of pi and p_{i-1}. We can model the quadratic Bezier line as following, here t is a number between 0 and 1: G_i(t)=(1-t)^2c_i +2(1-t)tp_i + t^2 c_{i+1} Consider the derivative against t: G_i'(t) = -2(1-t)c_i + 2(1-t-t)p_i + 2t c_{i+1}, and G_i''(t) = 2c_i -4p_i + 2c_{i+1} = 2p_{i-1} + 2 p_{i+1} Thus the second derivatives are constants. To show that the first derivatives match at each c_i, we can plug in t=0, and t=1. G_i'(0) = 2p_i-2c_i = p_i - p_{i-1} G_{i-1}'(1) = -2p_{i-1}+2c_i = p_i - p_{i-1} = G_i'(0)

顺便说一句,你可以看看维基贝塞尔曲线的明确定义https://en.wikipedia.org/wiki/B%C3%A9zier_curve

结帐此链接的原始代码: https://github.com/lyang36/codeNotes/blob/master/BezierCurveConstructor.java