2013-03-11 2 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; 

Freehand код:

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 это не полное решение, но оно дает вам представление о том, что вы можете сделать. –

+0

Эта статья о кривых Безье может быть полезна: http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/ – stan0

ответ

-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

Checkout ссылку для исходного кода : https://github.com/lyang36/codeNotes/blob/master/BezierCurveConstructor.java

Смежные вопросы