【问题标题】:How to draw a continuous curve goes through my touch points?如何绘制一条穿过我的接触点的连续曲线?
【发布时间】:2018-05-03 05:11:30
【问题描述】:

我在实现绘制贝塞尔曲线的代码时遇到了问题,该代码在 iOS 中运行良好。

我想要这个effect.,但需要接触点。

但我搞错了。 这一行的问题

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

【问题讨论】:

  • @Mike'Pomax'Kamermans 我已经编辑了我的问题,请查看它建议我。
  • 鉴于您的编辑,在查看代码之前:您是否寻找过适用于 Android 的软件包,这些软件包可以为您提供类似于您为 iOS 链接到的库的曲线通点?因为如果在使用了十年的 Android 之后,没有人需要它,也没有人写过,我会感到非常惊讶。
  • 那么,如何在android中得到这个效果呢?因为我搜索了很多,但我找不到足够的东西。
  • 效果来自于绘制 Catmull-Rom 曲线,并更改该曲线类型固有的“紧密度”值。我已经给你写了一个答案。

标签: android bezier cubic-bezier


【解决方案1】:

要实现您显示的链接中的效果,您需要实现 Catmull-Rom 曲线。值得庆幸的是,如果您正在使用已经可以绘制三次贝塞尔曲线的代码,那么实现这些是微不足道的,因为它们是相同的曲线,只是使用不同的表示,并且从一个转换为另一个是 incredibly easy

获取您的点列表,并为每个点创建切线,这些点与您正在查看的点之前和之后的点的线对齐。设置所有 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

然后绘制 catmull-rom 曲线(通过将每个 CR 部分的坐标转换为贝塞尔坐标并绘制相应的贝塞尔曲线),在转换为贝塞尔坐标之前,使用显示页面中的滑块控制“紧密度”因子.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多