计算两个xy点之间的四边形曲线

时间:2011-10-27 18:49:09

标签: java ios math animation

我有两个(x,y)点开始和结束。我想从头到尾制作动画,但不是采用线性方式,而是想创建一条曲线路径。

我很确定我不是在寻找缓和因为我不想影响动画速度,我只是想计算弯曲的路径。

我发现我需要某种控制点,如图所示:

enter image description here

但我不知道如何实现它。我很想创建一个带有以下参数的函数

function calculateXY(start, end, controlpoint, percentage);

其中百分比是0到100%之间的数字,其中0表示返回起始位置,100表示​​结束位置。

解决方案不需要在Objective-C中,它可以是任何编程语言。我只是无法理解数学:)

4 个答案:

答案 0 :(得分:3)

查看this链接,特别是方程式2,它看起来很容易在代码中实现。

找到了snippet,为您做到了这一点。

答案 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之间的时间间隔。介于两者之间的任何数字都是动画的时间分数。您想要的是在给定的时间内获取您的“兴趣点”的位置。第一步是,您拥有由两条线(AB)连接的三个点Cg => [AB]h => [BC]。对于这些行中的每行,您都必须计算在给定的时间段内,在startPoint和weightPoint P(g)之间以及分别在weightPoint和endPoint P(h)之间徘徊的点。

在这两个计算点(P(g)P(h))之间绘制第三条线(我们称其为y)。那条线上的某个地方就是您的“兴趣点”。但是哪里?同样,您必须计算从yP(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