How to make draw path smooth while drawing with variable width stroke

前端 未结 2 536
走了就别回头了
走了就别回头了 2021-02-03 14:56

I created a sample drawing app where the user can draw using variable width stroke, So far drawing a path with variable stroke is working, but the lines drawn are not smooth. Th

相关标签:
2条回答
  • 2021-02-03 15:38

    Your current code translates pretty much every touch move event (above a certain delta distance) into a new path segment. To make a smooth path, you need to do some processing on this large number of initial points that the user touched, and turn it into a smaller number of quad or cubic path segments.

    Have a look at the demo on this page: http://paperjs.org/tutorials/paths/smoothing-simplifying-flattening/#simplifying-paths and the corresponding simplification code: https://github.com/paperjs/paper.js/blob/master/src/path/PathFitter.js

    Obviously it's in JavaScript not Java, but you'll need to use a similar algorithm. An added complication will be that you will probably have to break down your smoothed path segments into multiple sub-segments again after smoothing to support varying stroke width within a single segment.

    0 讨论(0)
  • 2021-02-03 15:44

    Instead of jumping immediately to a new stroke width when you detect a change, you could set a target and interpolate toward it until you reach it. Your mStrokes would need to be Floats instead of Integers.

    private static final float STROKE_DELTA = 0.0001f; // for float comparison
    private static final float STROKE_INCREMENT = 0.01f; // amount to interpolate
    private float currentStroke = STROKE_WIDTH;
    private float targetStroke = STROKE_WIDTH;
    

    Where you currently create a new path for a new stroke width, do something like this:

    // if current not roughly equal to target
    if( Math.abs(targetStroke - currentStroke) > STROKE_DELTA ) {
        // move towards target by the increment
        if( targetStroke > currentStroke )
            currentStroke = Math.min(targetStroke, currentStroke + STROKE_INCREMENT);
        else
            currentStroke = Math.max(targetStroke, currentStroke - STROKE_INCREMENT);
        mPath.lineTo(mX, mY);
    
        mPath = new Path();
        mPath.moveTo(mX,mY);
        mPaths.add(mPath);
        mStrokes.add(currentStroke);
    }
    

    You would update targetStroke where you currently set variableWidthDelta.

    0 讨论(0)
提交回复
热议问题