Как нарисовать непрерывную кривую проходит через мои точки касания? - PullRequest
0 голосов
/ 03 мая 2018

У меня проблема с реализацией кода для рисования кривой Безье, которая отлично работает в iOS.

Я хочу этот эффект. , но с Touch Points.

Но я что-то не так делаю. Проблема в этой строке

previousCenterPoint = CenterPointOf(new PointF(points.get(0).x,points.get(0).y), previousPoint);

в iOS, используя currentPoint, мы можем получить текущую точку.

Подскажите, пожалуйста, как получить текущую точку контура пути ....

Вот мой код ..

public void makeBezierCurve(ArrayList<PointF> points) {
    if (points.size() > 0) {

        if (points.size() < 3) {

            switch (points.size()) {

                case 1:
                    lineTo(points.get(0).x, points.get(0).y);
                case 2:
                    lineTo(points.get(1).x, points.get(1).y);
                default:
                    break;
            }
        } else {


            PointF previousPoint = new PointF(0, 0);
            PointF previousCenterPoint = new PointF(0, 0);
            PointF centerPoint = new PointF(0, 0);
            double centerPointDistance = 0;
            double obliqueAngle = 0;
            PointF previousControlPoint1 = new PointF(0, 0);
            PointF previousControlPoint2 = new PointF(0, 0);
            PointF controlPoint1 = new PointF(0, 0);
            float contractionFactor = 0.7f;

            for (int i = 0; i < points.size(); i++) {

                PointF pointI = points.get(i);

                if (i > 0) {

                    previousCenterPoint = CenterPointOf(new PointF(points.get(0).x, points.get(0).y), previousPoint);
                    centerPoint = CenterPointOf(previousPoint, pointI);

                    centerPointDistance = DistanceBetween(previousCenterPoint, centerPoint);

                    obliqueAngle = ObliqueAngleOfStraightThrough(centerPoint, previousCenterPoint);

                    previousControlPoint2 = new PointF((float) (previousPoint.x - 0.5 * contractionFactor * centerPointDistance * Math.cos(obliqueAngle)), (float) (previousPoint.y - 0.5 * contractionFactor * centerPointDistance * Math.sin(obliqueAngle)));
                    controlPoint1 = new PointF((float) (previousPoint.x + 0.5 * contractionFactor * centerPointDistance * Math.cos(obliqueAngle)), (float) (previousPoint.y + 0.5 * contractionFactor * centerPointDistance * Math.sin(obliqueAngle)));
                }

                if (i == 1) {
                    quadTo(previousControlPoint2.x, previousControlPoint2.y, previousPoint.x, previousPoint.y);
                } else if (i >= 2 && i < points.size() - 1) {
                    cubicTo(previousControlPoint1.x, previousControlPoint1.y, previousControlPoint2.x, previousControlPoint2.y, previousPoint.x, previousPoint.y);
                } else if (i == points.size() - 1) {
                    cubicTo(previousControlPoint1.x, previousControlPoint1.y, previousControlPoint2.x, previousControlPoint2.y, previousPoint.x, previousPoint.y);
                    quadTo(controlPoint1.x, controlPoint1.y, pointI.x, pointI.y);
                }


                previousControlPoint1.set(controlPoint1);
                previousPoint.set(pointI);
            }
        }

    } else {
        logger.e("BezierHelper", "makeBezierCurve: error");
    }
}

1 Ответ

0 голосов
/ 05 мая 2018

Чтобы реализовать эффект от показанной ссылки, вам нужно реализовать кривые Catmull-Rom. К счастью, это несложно реализовать, если вы работаете с кодом, который уже может рисовать кубические кубы Безье, потому что они представляют собой одну и ту же кривую, просто используют другое представление, и преобразование из одного в другое невероятно просто .

Возьмите список своих точек и придумайте касательные для каждой точки, которые выровнены по линии от точек до и после той, на которую вы смотрите. Общий код для получения всех ваших очков CR:

points = ...
initialpoint = points[0] - (points[1] - points[0]) // invent a 'virtual' -1th point
finalpoint = points[last] + (points[last] - points[last-1]) // invent a 'virtual' (last+1)th point
points = initialpoint + points + finalpoint
foreach ((point,i) in points) {
  try {
    p = points[i-1]
    n = points[i+1]
  } catch { continue } 
  diff = n-p 
  point.tangent = diff/2 // let's be reasonable 
}
points = points.slice(1,last-1) // throw those virtual points away

Затем нарисуйте кривую Катмулла (преобразовав координаты для каждой секции CR в координаты Безье и нарисовав соответствующую кривую Безье), с помощью ползунка на странице, который вы показываете, управляющего коэффициентом "герметичности", прежде чем переходить к координатам Безье. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...