Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用bezier时的签名捕获缺陷_Android_Curve_Bezier_Handwriting Recognition - Fatal编程技术网

Android 使用bezier时的签名捕获缺陷

Android 使用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

我试图通过以下使用bezier类的链接捕获数字签名

当签名没有举起手指时,我能正确地画出签名。但当我抬起手指再次开始签名时,它会画一条连接上一点和新点的线。

在上面的图片中,我画了5个点。但它不是点而是从第一个点到另一个点画一条线

Bezier.java

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;
}