简体   繁体   English

在两点之间绘制曲线

[英]Draw curved line between two points

I can't even remember since when I've been looking for a way to draw a curved line between two points.我什至不记得从什么时候开始我一直在寻找一种在两点之间绘制曲线的方法。

I've tried many things like QuadCurves2D , Bezier Curve, etc..., but I'm failing to find a control point.我已经尝试了很多东西,比如QuadCurves2D 、 Bezier Curve 等……,但我没有找到控制点。

The idea here is to draw a curved line between two points independently where they are or which angle between them(user can change the points' position by clicking alt and dragging it over the screen)这里的想法是在两个点之间独立绘制一条曲线,它们的位置或它们之间的角度(用户可以通过单击 alt 并在屏幕上拖动来更改点的位置)

This is what I've got so far...这是我到目前为止所得到的......两点之间的错误曲线

As you can see above, the curve is absolutely wrong.正如你在上面看到的,曲线是完全错误的。

What I expect is something like this:我期望的是这样的:

正确的曲线

Step one: axis-align your two points so that one of them's on (0,0), and the other's on ([...],0).第一步:轴对齐您的两个点,使其中一个在 (0,0) 上,另一个在 ([...],0) 上。 Let's say we have two points,假设我们有两点,

P1 = {a,b)
P2 = {c,d}

we translate them so that p1's on 0,0:我们将它们转换为 p1 位于 0,0:

P1 = {0,0}
P2 = {c-a,d-b}

then we rotate p2 about (0,0) so that it ends up lying on the x-axis:然后我们将 p2 旋转 (0,0) 使其最终位于 x 轴上:

a = -atan2(dy,dx) = -atan2(d-b, c-a)
P2ʹ = {
  p2.x * cos(a) - p2.y * sin(a),
  p2.x * sin(a) + p2.y * cos(a)
}

note the - in front of the atan2 call because we don't want to know the angle "from axis to point", but from point to x-axis.注意 - 在atan2调用之前,因为我们不想知道“从轴到点”的角度,而是从点到 x 轴的角度。 We now have two axis-aligned points (let's call that rotated x-coordinate for the new P2 "v"):我们现在有两个轴对齐的点(让我们将新 P2 的旋转 x 坐标称为“v”):

P1  = { 0 , 0 }
P2ʹ = { v , 0 }

We can now do whatever we want in terms of curve construction.我们现在可以在曲线构建方面做任何我们想做的事情。 While usually pretty ugly, we can construct a quadratic curve with a control point that's at (v/2, ...) and has a height "whatever you want based on how strong you want the curvature to be. This will give us a coordinate relative to the transform-invariant coordinates, so we just apply the rotation/translation in reverse:虽然通常很难看,但我们可以构建一个二次曲线,其控制点位于(v/2, ...)并且具有高度“任何你想要的基于你想要曲率的强度。这会给我们一个坐标相对于变换不变坐标,所以我们只需反向应用旋转/平移:

C  = (v/2,h), then rotate by -a, then translate by (a,b)

(note that - sign again). (请注意 - 再次签名)。 We already know where P1 and P2 were, so we don't need to do any computing there.我们已经知道 P1 和 P2 在哪里,所以我们不需要在那里做任何计算。 Bezier curves are defined by their "hull points" and well-behaved with regards to linear transformations so all this translation/rotation business makes not difference to the algorithm that draws the curves.贝塞尔曲线由它们的“船体点”定义,并且在线性变换方面表现良好,因此所有这些平移/旋转业务与绘制曲线的算法没有区别。 Just plug the six values into the quadratic draw functions and presto.只需将六个值插入二次绘制函数中即可。 A curve from P1 to P2 controlled by C.由 C 控制的从 P1 到 P2 的曲线。

Of course you probably want a cubic curve instead because quadratic curves are quite ugly, so instead of defining a C, we can define a C1 and C2:当然,您可能需要三次曲线,因为二次曲线非常丑陋,因此我们可以定义 C1 和 C2,而不是定义 C:

C1 = (v/3, 0)
C2 = (2*v/3, 0)

and then raise/lower them both by the same amount;然后将它们升高/降低相同的数量; then we anti-rotate and anti-translate them and plug the P1, C1, C2, P2 we now have into a cubic bezier drawing function: done.然后我们反旋转和反平移它们并将我们现在拥有的 P1、C1、C2、P2 插入三次贝塞尔绘图函数:完成。 Pretty curves.漂亮的曲线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM