我有两个(x,y)点开始和结束。我想从头到尾制作动画,但不是采用线性方式,而是想创建一条曲线路径。
我很确定我不是在寻找缓和因为我不想影响动画速度,我只是想计算弯曲的路径。
我发现我需要某种控制点,如图所示:
但我不知道如何实现它。我很想创建一个带有以下参数的函数
function calculateXY(start, end, controlpoint, percentage);
其中百分比是0到100%之间的数字,其中0表示返回起始位置,100表示结束位置。
解决方案不需要在Objective-C中,它可以是任何编程语言。我只是无法理解数学:)
答案 0 :(得分:3)
答案 1 :(得分:0)
请看Cocoa's bezier paths: (NSBezierPath)。
看起来它可能不支持二次贝塞尔曲线,因此您需要convert to cubic。
答案 2 :(得分:0)
该解决方案无需使用Objective-C,它可以采用任何编程语言。我只是无法理解数学
我无法提供代码,但是如果您对所涉及的数学有所了解,我可以解释一下它对Quad曲线的作用。
首先了解控制点在数学上的影响。控制点和两个定义的点定义了在当前点和端点处绘制的线的渐变。您可以使用m =(y-y1)/(x-x1)计算两条直线的梯度。
从数学上讲,您接下来要解决的是针对a,b,c的这组方程:
ax ^ 2 + bx + c包含起点和终点
2ax + b等于相应x值处的相应梯度。
到那时,您可以使用二次方来画线。
答案 3 :(得分:0)
我在工作中看到了此事,想在家中拍照。在看了this example from Wikipedia一段时间后,我想我知道了,该怎么做,下面您将找到一个示例,我现在将对其进行解释。
我将使用0到1之间的时间间隔。介于两者之间的任何数字都是动画的时间分数。您想要的是在给定的时间内获取您的“兴趣点”的位置。第一步是,您拥有由两条线(A
,B
)连接的三个点C
,g => [AB]
,h => [BC]
。对于这些行中的每行,您都必须计算在给定的时间段内,在startPoint和weightPoint P(g)
之间以及分别在weightPoint和endPoint P(h)
之间徘徊的点。
在这两个计算点(P(g)
和P(h)
)之间绘制第三条线(我们称其为y
)。那条线上的某个地方就是您的“兴趣点”。但是哪里?同样,您必须计算从y
到P(y)
行的P(g)
(称为P(h)
)线上的点的位置。
您正在寻找P(y)
的职位。
function setup() {
createCanvas(400, 400);
fraction = 0;
drawnPoints = [];
}
function draw() {
background(100);
let start = new Point(30, 50, 5);
let end = new Point(300, 170, 5);
let weight = new Point(200, 300, 5);
let lineStartWeight = new Line(start, weight);
let lineStartWeightPoint = lineStartWeight.getPointAt(fraction);
let lineWeightEnd = new Line(weight, end);
let lineWeightEndPoint = lineWeightEnd.getPointAt(fraction);
let drawingLine = new Line(lineStartWeightPoint, lineWeightEndPoint);
start.draw('red');
end.draw('blue');
weight.draw('#0f0');
lineStartWeight.draw('#ff0');
lineWeightEnd.draw('#0ff');
lineStartWeightPoint.draw('#000');
lineWeightEndPoint.draw('#fff')
drawingLine.draw('#f66');
drawnPoints.push(drawingLine.getPointAt(fraction));
drawnPoints.forEach(p => p.draw(''));
fraction += 0.01
if (fraction > 1) {
fraction = 0;
drawnPoints = [];
}
}
class Point {
constructor(x, y, size = 1) {
this.x = x;
this.y = y;
this.size = size;
}
draw(color) {
fill(color);
noStroke();
ellipse(this.x, this.y, this.size, this.size);
}
}
class Line {
constructor(pointStart, pointEnd) {
this.pointStart = pointStart;
this.pointEnd = pointEnd;
}
draw(color) {
stroke(color);
line(this.pointStart.x, this.pointStart.y, this.pointEnd.x, this.pointEnd.y);
}
getPointAt(fraction) {
let xCoord = (this.pointEnd.x - this.pointStart.x) * fraction + this.pointStart.x;
let yCoord = (this.pointEnd.y - this.pointStart.y) * fraction + this.pointStart.y;
return new Point(xCoord, yCoord, 5);
}
}
html, body {
margin: 0;
padding: 0;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/addons/p5.dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
编辑
它归结为一个简单的功能。我将仅针对x值进行说明,但y的工作原理类似。
开始(x 1 | y 1 ),结束(x 2 | y 2 ),控制点(x 3 | y 3 ),f =动画时间的一部分
要在某个时间点f获得x值,您可以:
x =((((x 2 -x 3 )* f + x 3 )-(((x 3 < / sub> -x 1 )* f + x 1 ))* f +((x 3 -x 1 )* f + x 1 )
经过一些简化,您得出:
x = f 2 (x 1 + x 2 -2x 3 ) + 2f(x 3 -x 1 )+ x 1