Example usage for android.graphics PathMeasure getPosTan

List of usage examples for android.graphics PathMeasure getPosTan

Introduction

In this page you can find the example usage for android.graphics PathMeasure getPosTan.

Prototype

public boolean getPosTan(float distance, float pos[], float tan[]) 

Source Link

Document

Pins distance to 0 <= distance <= getLength(), and then computes the corresponding position and tangent.

Usage

From source file:android.support.transition.PatternPathMotion.java

/**
 * Sets the Path defining a pattern of motion between two coordinates.
 * The pattern will be translated, rotated, and scaled to fit between the start and end points.
 * The pattern must not be empty and must have the end point differ from the start point.
 *
 * @param patternPath A Path to be used as a pattern for two-dimensional motion.
 *//*from  ww  w  .  j  av a 2  s  .com*/
public void setPatternPath(Path patternPath) {
    PathMeasure pathMeasure = new PathMeasure(patternPath, false);
    float length = pathMeasure.getLength();
    float[] pos = new float[2];
    pathMeasure.getPosTan(length, pos, null);
    float endX = pos[0];
    float endY = pos[1];
    pathMeasure.getPosTan(0, pos, null);
    float startX = pos[0];
    float startY = pos[1];

    if (startX == endX && startY == endY) {
        throw new IllegalArgumentException("pattern must not end at the starting point");
    }

    mTempMatrix.setTranslate(-startX, -startY);
    float dx = endX - startX;
    float dy = endY - startY;
    float distance = distance(dx, dy);
    float scale = 1 / distance;
    mTempMatrix.postScale(scale, scale);
    double angle = Math.atan2(dy, dx);
    mTempMatrix.postRotate((float) Math.toDegrees(-angle));
    patternPath.transform(mTempMatrix, mPatternPath);
    mOriginalPatternPath = patternPath;
}

From source file:com.lauszus.dronedraw.DroneDrawActivity.java

private void uploadCsvFile() {
    if (!mDrawView.mFullPath.isEmpty()) {
        File csvFileLocation = new File(getFilesDir(), "path.csv");
        try {// ww  w  .  ja va  2  s. c om
            CSVWriter writer = new CSVWriter(new FileWriter(csvFileLocation), ',',
                    CSVWriter.NO_QUOTE_CHARACTER);
            final int dataSize = 10 * mDrawView.touchCounter; // Sample path 10 times more than actual touches
            for (int i = 0; i <= dataSize; i++) {
                PathMeasure mPathMeasure = new PathMeasure(mDrawView.mFullPath, false);

                final float t = (float) i / (float) dataSize;
                float[] xy = new float[2];
                mPathMeasure.getPosTan(mPathMeasure.getLength() * t, xy, null);

                // Normalize coordinates based on maximum dimension
                final float maxDimension = Math.max(mDrawView.getWidth(), mDrawView.getHeight());
                final float x = xy[0] / maxDimension;
                final float y = (mDrawView.getHeight() - xy[1]) / maxDimension; // Make y-axis point upward

                writer.writeNext(new String[] { Integer.toString(i), Float.toString(x), Float.toString(y) });

                //if (D) Log.d(TAG, "t: " + t + " x: " + x + " y: " + y);
            }
            writer.close();
            //sendEmail(csvFileLocation);
            uploadFileToDropbox(csvFileLocation);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

From source file:com.facebook.keyframes.util.KFPathInterpolator.java

public KFPathInterpolator(float controlX1, float controlY1, float controlX2, float controlY2) {
    Path path = new Path();
    path.moveTo(0, 0);//from  w w  w .jav a2 s  . c  om
    path.cubicTo(controlX1, controlY1, controlX2, controlY2, 1f, 1f);
    final PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */);
    final float pathLength = pathMeasure.getLength();
    final int numPoints = (int) (pathLength / PRECISION) + 1;
    mX = new float[numPoints];
    mY = new float[numPoints];
    final float[] position = new float[2];
    for (int i = 0; i < numPoints; ++i) {
        final float distance = (i * pathLength) / (numPoints - 1);
        pathMeasure.getPosTan(distance, position, null /* tangent */);
        mX[i] = position[0];
        mY[i] = position[1];
    }
}

From source file:android.support.wear.widget.util.ArcSwipe.java

private float[][] interpolate(float[] start, float[] end, int steps, boolean isClockwise) {
    float startAngle = getAngle(start[0], start[1]);
    float endAngle = getAngle(end[0], end[1]);

    Path path = new Path();
    PathMeasure pathMeasure = new PathMeasure();
    path.moveTo(start[0], start[1]);/*from  w ww.ja  va 2s. co  m*/
    path.arcTo(mBounds, startAngle, getSweepAngle(startAngle, endAngle, isClockwise));
    pathMeasure.setPath(path, false);
    float pathLength = pathMeasure.getLength();

    float[][] res = new float[steps][2];
    float[] mPathTangent = new float[2];

    for (int i = 1; i < steps + 1; i++) {
        pathMeasure.getPosTan((pathLength * i) / (steps + 2f), res[i - 1], mPathTangent);
    }

    return res;
}

From source file:android.support.graphics.drawable.AnimatorInflaterCompat.java

private static void setupPathMotion(Path path, ObjectAnimator oa, float precision, String propertyXName,
        String propertyYName) {/*  w  w w .  ja  v a 2s . c o  m*/
    // Measure the total length the whole path.
    final PathMeasure measureForTotalLength = new PathMeasure(path, false);
    float totalLength = 0;
    // The sum of the previous contour plus the current one. Using the sum here b/c we want to
    // directly substract from it later.
    ArrayList<Float> contourLengths = new ArrayList<>();
    contourLengths.add(0f);
    do {
        final float pathLength = measureForTotalLength.getLength();
        totalLength += pathLength;
        contourLengths.add(totalLength);

    } while (measureForTotalLength.nextContour());

    // Now determine how many sample points we need, and the step for next sample.
    final PathMeasure pathMeasure = new PathMeasure(path, false);

    final int numPoints = min(MAX_NUM_POINTS, (int) (totalLength / precision) + 1);

    float[] mX = new float[numPoints];
    float[] mY = new float[numPoints];
    final float[] position = new float[2];

    int contourIndex = 0;
    float step = totalLength / (numPoints - 1);
    float currentDistance = 0;

    // For each sample point, determine whether we need to move on to next contour.
    // After we find the right contour, then sample it using the current distance value minus
    // the previously sampled contours' total length.
    for (int i = 0; i < numPoints; ++i) {
        pathMeasure.getPosTan(currentDistance, position, null);
        pathMeasure.getPosTan(currentDistance, position, null);

        mX[i] = position[0];
        mY[i] = position[1];
        currentDistance += step;
        if ((contourIndex + 1) < contourLengths.size()
                && currentDistance > contourLengths.get(contourIndex + 1)) {
            currentDistance -= contourLengths.get(contourIndex + 1);
            contourIndex++;
            pathMeasure.nextContour();
        }
    }

    // Given the x and y value of the sample points, setup the ObjectAnimator properly.
    PropertyValuesHolder x = null;
    PropertyValuesHolder y = null;
    if (propertyXName != null) {
        x = PropertyValuesHolder.ofFloat(propertyXName, mX);
    }
    if (propertyYName != null) {
        y = PropertyValuesHolder.ofFloat(propertyYName, mY);
    }
    if (x == null) {
        oa.setValues(y);
    } else if (y == null) {
        oa.setValues(x);
    } else {
        oa.setValues(x, y);
    }
}

From source file:android.support.graphics.drawable.PathInterpolatorCompat.java

private void initPath(Path path) {
    final PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */);

    final float pathLength = pathMeasure.getLength();
    final int numPoints = min(MAX_NUM_POINTS, (int) (pathLength / PRECISION) + 1);

    if (numPoints <= 0) {
        throw new IllegalArgumentException("The Path has a invalid length " + pathLength);
    }/*from   ww  w.  ja  va2s. c  o m*/

    mX = new float[numPoints];
    mY = new float[numPoints];

    final float[] position = new float[2];
    for (int i = 0; i < numPoints; ++i) {
        final float distance = (i * pathLength) / (numPoints - 1);
        pathMeasure.getPosTan(distance, position, null /* tangent */);

        mX[i] = position[0];
        mY[i] = position[1];
    }

    if (abs(mX[0]) > EPSILON || abs(mY[0]) > EPSILON || abs(mX[numPoints - 1] - 1) > EPSILON
            || abs(mY[numPoints - 1] - 1) > EPSILON) {
        throw new IllegalArgumentException("The Path must start at (0,0) and end at (1,1)" + " start: " + mX[0]
                + "," + mY[0] + " end:" + mX[numPoints - 1] + "," + mY[numPoints - 1]);

    }

    float prevX = 0;
    int componentIndex = 0;
    for (int i = 0; i < numPoints; i++) {
        float x = mX[componentIndex++];
        if (x < prevX) {
            throw new IllegalArgumentException("The Path cannot loop back on itself, x :" + x);
        }
        mX[i] = x;
        prevX = x;
    }

    if (pathMeasure.nextContour()) {
        throw new IllegalArgumentException("The Path should be continuous," + " can't have 2+ contours");
    }
}

From source file:com.github.shareme.gwsmaterialuikit.library.viewanimator.AnimationBuilder.java

/**
 * ?/*from ww w  .j  a  v a2  s . c o m*/
 *
 * @param path the path
 * @return the animation builder
 * @link http://blog.csdn.net/tianjian4592/article/details/47067161
 */
public AnimationBuilder path(Path path) {
    if (path == null) {
        return this;
    }
    final PathMeasure pathMeasure = new PathMeasure(path, false);
    return custom(new AnimationListener.Update() {
        @Override
        public void update(View view, float value) {
            float[] currentPosition = new float[2];// ???
            pathMeasure.getPosTan(value, currentPosition, null);
            final float x = currentPosition[0];
            final float y = currentPosition[1];
            ViewCompat.setX(view, x);
            ViewCompat.setY(view, y);
            Timber.d("path: value=" + value + ", x=" + x + ", y=" + y);
        }
    }, 0, pathMeasure.getLength());
}

From source file:com.waz.zclient.views.images.CircularSeekBar.java

private void calculatePointerXYPosition() {
    PathMeasure pm = new PathMeasure(circleProgressPath, false);
    boolean returnValue = pm.getPosTan(pm.getLength(), pointerPositionXY, null);
    if (!returnValue) {
        pm = new PathMeasure(circlePath, false);
        returnValue = pm.getPosTan(0, pointerPositionXY, null);
    }//from w  ww  .  j  av a 2s . c  om
}

From source file:de.uni_weimar.mheinz.androidtouchscope.display.ScopeView.java

private float smallestDistanceToPath(Path path, float x, float y) {
    PathMeasure measure = new PathMeasure(path, false);
    float pos[] = { 0f, 0f };
    float minDist = 1000f;
    float dist;//from w  w w. j  av a 2s .  c  om

    for (int i = 0; i < measure.getLength(); ++i) {
        measure.getPosTan(i, pos, null);
        dist = (float) Math.hypot(x - pos[0], y - pos[1]);
        if (dist < minDist)
            minDist = dist;
    }
    return minDist;
}