So zeichnen Sie einen Pfad mit variabler Strichbreite

Mein Code ist im Grunde aus diesem Beispiel (http://corner.squareup.com/2010/07/smooth-signatures.html) und Google APIs (FingerPaint), aber jetzt möchte ich die Klasse verwendenVelocityTracker um die Strichstärke in Abhängigkeit von der Geschwindigkeit meines Fingers zu ändern.

Ich dachte, ich könnte einen Pfad in kleinere Teile aufteilen, fand aber keine Beispiele. Es gibt auch diesen zweiten Beitrag (http://corner.squareup.com/2012/07/smoother-signatures.html), aber ich habe weder eine bestimmte Bezierkurvenklasse noch sammle ich alle Punkte in einemArrayList Daher ist ihr Beispiel für die Einstellung der Strichstärke nicht sehr hilfreich.

Hat jemand eine Idee, wie man damit umgeht? Ich habe vor zwei Wochen angefangen, Code zu lernen, deshalb bin ich in all diesen Dingen ziemlich neu.

Bearbeiten: Ich habe versucht, die Geschwindigkeit meiner MotionEvents zu implementieren, und ich habe LogCat verwendet, um die aktuelle Geschwindigkeit zu verfolgen, während die App ausgeführt wurde. Es hat geklappt, aber als ich versuchte, die Velocity als Teil des Parameters für mPaint.setStrokeWidth zu verwenden, bekam ich nicht das, was ich eigentlich wollte. Die Breite des Pfads, den ich auf meiner Leinwand zeichne, änderte sich von dem Moment an, als ich anfing, eine Linie zu zeichnen, bis ich meinen Finger nach oben bewegte. Aus diesem Grund möchte ich einen Pfad in kleinere Teile aufteilen, da nur die zuletzt verfolgte Geschwindigkeit die Strichbreite beeinflusst.

public class SignatureView extends View {

    private static final String TAG = SignatureView.class.getSimpleName();
    private static final float STROKE_WIDTH = 10;
    private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
    private final double TOUCH_TOLERANCE = 5;
    private int h = getResources().getDisplayMetrics().heightPixels;
    private int w = getResources().getDisplayMetrics().widthPixels;

    private Path mPath = new Path();
    private Paint mPaint = new Paint();
    private Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    private Bitmap mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    private Canvas mCanvas = new Canvas(mBitmap);

    private float mX, mY;
    private float lastTouchX, lastTouchY;
    private final RectF dirtyRect = new RectF();

public SignatureView(Context context, AttributeSet attrs) {
    super(context, attrs);

    mPaint.setAntiAlias(true);
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeWidth(INITIAL_STROKE_WIDTH);

    Log.d(TAG, "TOUCH_TOLERANCE = " +TOUCH_TOLERANCE);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);            
    canvas.drawPath(mPath, mPaint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float eventX = event.getX();
    float eventY = event.getY();
    int historySize = event.getHistorySize();

    switch (event.getAction()) {

        case MotionEvent.ACTION_DOWN:

            resetDirtyRect(eventX, eventY);
            mPath.reset();
            mPath.moveTo(eventX, eventY);
            mX = eventX;
            mY = eventY;
            break;

        case MotionEvent.ACTION_MOVE:

            float dx = Math.abs(eventX - mX);
            float dy = Math.abs(eventY - mY);

            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {

                mPath.quadTo(mX, mY, (eventX + mX)/2, (eventY + mY)/2);
                mX = eventX;
                mY = eventY;
            }

            for (int i = 0; i < historySize; i++) {
                float historicalX = event.getHistoricalX(i);
                float historicalY = event.getHistoricalY(i);
                expandDirtyRect(historicalX, historicalY);
            }
            break;

        case MotionEvent.ACTION_UP:

            for (int i = 0; i < historySize; i++) {
                float historicalX = event.getHistoricalX(i);
                float historicalY = event.getHistoricalY(i);
                expandDirtyRect(historicalX, historicalY);
            }

            mPath.lineTo(mX, mY);
            mCanvas.drawPath(mPath, mPaint);
            mPath.reset();
            break;

        default:
            Log.d(TAG, "Ignored touch event: " + event.toString());
        return false;
    }

    // Include half the stroke width to avoid clipping.
        invalidate(     (int) (dirtyRect.left - HALF_STROKE_WIDTH),
                        (int) (dirtyRect.top - HALF_STROKE_WIDTH),
                        (int) (dirtyRect.right + HALF_STROKE_WIDTH),
                        (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));

    lastTouchX = eventX;
    lastTouchY = eventY;
    return true;
}

private void expandDirtyRect(float historicalX, float historicalY) {
    if (historicalX < dirtyRect.left) {
        dirtyRect.left = historicalX;
    } else if (historicalX > dirtyRect.right) {
        dirtyRect.right = historicalX;
    }
    if (historicalY < dirtyRect.top) {
        dirtyRect.top = historicalY;
    } else if (historicalY > dirtyRect.bottom) {
        dirtyRect.bottom = historicalY;
    }
}

private void resetDirtyRect(float eventX, float eventY) {

    dirtyRect.left = Math.min(lastTouchX, eventX);
    dirtyRect.right = Math.max(lastTouchX, eventX);
    dirtyRect.top = Math.min(lastTouchY, eventY);
    dirtyRect.bottom = Math.max(lastTouchY, eventY);
}
}

Antworten auf die Frage(1)

Ihre Antwort auf die Frage