Android 使用bezier时的签名捕获缺陷
我试图通过以下使用bezier类的链接捕获数字签名 当签名没有举起手指时,我能正确地画出签名。但当我抬起手指再次开始签名时,它会画一条连接上一点和新点的线。 在上面的图片中,我画了5个点。但它不是点而是从第一个点到另一个点画一条线 Bezier.javaAndroid 使用bezier时的签名捕获缺陷,android,curve,bezier,handwriting-recognition,Android,Curve,Bezier,Handwriting Recognition,我试图通过以下使用bezier类的链接捕获数字签名 当签名没有举起手指时,我能正确地画出签名。但当我抬起手指再次开始签名时,它会画一条连接上一点和新点的线。 在上面的图片中,我画了5个点。但它不是点而是从第一个点到另一个点画一条线 Bezier.java public class Bezier { private Point controlPointOne; private Point controlPointTwo; private int drawSteps; private Point
public class Bezier {
private Point controlPointOne;
private Point controlPointTwo;
private int drawSteps;
private Point endPoint;
private int mColor;
private Point startPoint;`
public Bezier() {
}
public Bezier(Point paramPoint1, Point paramPoint2, Point paramPoint3,
Point paramPoint4) {
this.startPoint = paramPoint1;
this.controlPointOne = paramPoint2;
this.controlPointTwo = paramPoint3;
this.endPoint = paramPoint4;
this.drawSteps = ((int) (paramPoint1.distanceTo(paramPoint2)
+ paramPoint2.distanceTo(paramPoint3) + paramPoint3
.distanceTo(paramPoint4)));
}
public void draw(Canvas canvas, Paint paint, float startWidth, float endWidth) {
float originalWidth = paint.getStrokeWidth();
float widthDelta = endWidth - startWidth;
for (int i = 0; i < drawSteps; i++) {
float t = ((float) i) / drawSteps;
float tt = t * t;
float ttt = tt * t;
float u = 1 - t;
float uu = u * u;
float uuu = uu * u;
float x = uuu * startPoint.x;
x += 3 * uu * t * getControlPointOne().x;
x += 3 * u * tt * getControlPointTwo().x;
x += ttt * endPoint.x;
float y = uuu * startPoint.y;
y += 3 * uu * t * getControlPointOne().y;
y += 3 * u * tt * getControlPointTwo().y;
y += ttt * endPoint.y;
paint.setStrokeWidth(startWidth + ttt * widthDelta);
canvas.drawPoint(x, y, paint);
}
paint.setStrokeWidth(originalWidth);
}
public int getColor() {
return this.mColor;
}
public Point getControlPointOne() {
return this.controlPointOne;
}
public Point getControlPointTwo() {
return this.controlPointTwo;
}
public int getDrawSteps() {
return this.drawSteps;
}
public Point getEndPoint() {
return this.endPoint;
}
public Point getStartPoint() {
return this.startPoint;
}
public void setColor(int paramInt) {
this.mColor = Color.BLACK;
}
public void setControlPointOne(Point paramPoint) {
this.controlPointOne = paramPoint;
}
public void setControlPointTwo(Point paramPoint) {
this.controlPointTwo = paramPoint;
}
public void setDrawSteps(int paramInt) {
this.drawSteps = paramInt;
}
public void setEndPoint(Point paramPoint) {
this.endPoint = paramPoint;
}
public void setStartPoint(Point paramPoint) {
this.startPoint = paramPoint;
}
在onTouchEvent事件处理程序中,您应该观察MotionEvent.ACTION\u DOWN和MotionEvent.ACTION\u UP事件,因为它们标记手势的开始和结束
private boolean drawing = false;
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Mark drawing as started
drawing = true;
path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
// Draw after ACTION_DOWN
if (drawing) {
path.lineTo(eventX, eventY);
}
break;
case MotionEvent.ACTION_UP:
if (drawing) {
path.lineTo(eventX, eventY);
// Mark drawing as finished
drawing = false;
}
break;
default:
return false;
}
if (drawing) {
// Schedules a repaint.
invalidate();
}
return true;
}
避免使用命名常量的值并除以零。通过代码以手指速度绘制曲线=您根本不需要贝塞尔曲线,您需要的是Catmull-Rom。它们通过以特定速度通过点来进行专门定义。这两个都是Hermite曲线,可以相互转换而不损失精度,但您确实只想直接使用Catmull Rom,但如示例链接中所示,当用户想要在两个单独的单词上签名时,则不能将这两个单词用一条线连接起来。@RahulVarma您能解决这个问题吗?
public class Point {
private long time;
float x;
float y;
public Point(float paramFloat1, float paramFloat2) {
this.x = paramFloat1;
this.y = paramFloat2;
}
public Point(float paramFloat1, float paramFloat2, long paramLong) {
this.x = paramFloat1;
this.y = paramFloat2;
this.time = paramLong;
}
protected float distanceTo(Point paramPoint) {
float f1 = this.x - paramPoint.getX();
float f2 = this.y - paramPoint.getY();
return FloatMath.sqrt(f1 * f1 + f2 * f2);
}
public long getTime() {
return this.time;
}
public float getX() {
return this.x;
}
public float getY() {
return this.y;
}
public void setX(float paramFloat) {
this.x = paramFloat;
}
public void setY(float paramFloat) {
this.y = paramFloat;
}
public float velocityFrom(Point start) {
return distanceTo(start) / (this.time - start.time);
}
}
private boolean drawing = false;
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Mark drawing as started
drawing = true;
path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
// Draw after ACTION_DOWN
if (drawing) {
path.lineTo(eventX, eventY);
}
break;
case MotionEvent.ACTION_UP:
if (drawing) {
path.lineTo(eventX, eventY);
// Mark drawing as finished
drawing = false;
}
break;
default:
return false;
}
if (drawing) {
// Schedules a repaint.
invalidate();
}
return true;
}