简体   繁体   English

在JavaScript中围绕路径制作正弦波曲线

[英]Making a sine wave curve around a path in javascript

I am trying to figure out a nice way to make a sine wave flow naturally along a javascript path. 我试图找出一种很好的方法来使正弦波自然地沿着javascript路径流动。 I made something like this: 我做了这样的事情:

在此处输入图片说明

Which captures some of the intent but it's very forced and unnatural, especially around the change direction. 捕获了一些意图,但是它是非常强迫和不自然的,尤其是在变更方向周围。 I also would love to accommodate for higher slope, but not sure if that ives a more natural effect or not. 我也很想适应更高的坡度,但是不确定是否能带来更自然的效果。

Any thoughts on how I might be able to accomplish this? 关于我如何能够做到这一点的任何想法?

The intent was: 目的是:

1) Take a set of points 1)取一点

2) Break into equal segments 2)分成相等的段

3) Adjust the actual line's position by the difference of the sin coords and the actual line coords. 3)通过正弦坐标和实际坐标的差来调整实际坐标的位置。

This gives a pretty weak display though, and I'd like to create something that was more natural and flowing as if to capture the flow of a sine wave travelling along a path. 但是,这会产生非常弱的显示效果,我想创建一种更自然,更流畅的东西,好像捕获沿路径传播的正弦波的流动一样。

var c = document.getElementById("c");
var ctx = c.getContext("2d");
var cw = c.width = window.innerWidth;
var ch = c.height = window.innerHeight;
var cx = cw / 2,
  cy = ch / 2;
var rad = Math.PI / 180;
var w = cw;
var h = ch * 0.3;
var amplitude = h;
var frequency = 0.01;
var phi = 0;
var frames = 0;
var stopped = true;
ctx.lineWidth = .4;

var offset = 100;

var points = interpolateLineRange( [ [0, 0], [ 95, 58], [84, 158], [350, 300], [540, 190] ], 20);
points = interpolateLineRange(points, 100);

ctx.moveTo(0, 0);
var distance_traveled = 0;
var current_slope = 0;

for (var ii in points) {

  if (ii == 0) {
    continue;
  }
  distance_traveled += dist(points[ii - 1], points[ii]);
  current_slope = slope(points[ii - 1], points[ii]);

  var newY = Math.sin(distance_traveled * .07) * 45 + points[ii][1];
  var diff = newY - points[ii][1];

  if (points[ii][1] > points[ii - 1][1]) {
    ctx.lineTo(points[ii][0] - diff, newY);
  } else {
    ctx.lineTo(points[ii][0] + diff, newY);
  }
}

ctx.stroke();
ctx.moveTo(0, 0);

for (var ii in points) {
  ctx.lineTo(points[ii][0], points[ii][1]);
}
ctx.strokeStyle = 'red';
ctx.stroke();

The problem isn't really "drawing sine waves along a path": that part is actually trivial. 问题并不是真正的“沿路径绘制正弦波”:这部分实际上是微不足道的。 Take your path section, express it in terms of a distance or time variable, and then draw the sines (or anything else) as an offset function: 采取路径部分,用距离或时间变量表示,然后将正弦(或其他任何东西)绘制为偏移函数:

for t=0; t<distance; t+=fraction of distance:
  point = path.get(t)
  normal = path.normal(t)
  strength = sin(t)
  if t=0:
    ctx.moveTo(point + strength * normal)
  else: 
    ctx.lineTo(point + strength * normal)

Easy enough, let's implement that: http://jsbin.com/nefemazovo/edit?js,output 足够简单,让我们实现一下: http : //jsbin.com/nefemazovo/edit?js,输出

Sure, it's a bit of code, but it's hardly complicated: just a class that models a polygonal path that tracks its length as we add points to it, and a draw function that draws the polygon, as well as some offset function, by sampling the polygon at regular intervals and computing the normal at each point. 当然,这是一些代码,但是却并不复杂:只是一个模拟多边形路径的类(当我们向其添加点时跟踪其长度),以及一个通过采样绘制多边形的绘制函数以及一些偏移函数以规则的间隔绘制多边形并计算每个点的法线。

The real question is: how are you going to deal with overlaps in your offset data? 真正的问题是:您将如何处理偏移数据中的重叠? For instance, from the example above: 例如,从上面的示例中:

在此处输入图片说明

There's a pretty obvious area here where we're going to have to do ... something: 这里有一个非常明显的区域,我们需要做的事情...

在此处输入图片说明

So what do we do? 那么我们该怎么办? Turns out: no one knows, that's really up to you. 结果:没人知道,这完全取决于您。 For instance, you could draw "uneven" sines so that you always end up with a node at the end points of your polygonal sections. 例如,您可能会绘制“不均匀”的正弦,以便始终在多边形截面的终点处结一个节点。 Might work, but you might also still have overlap if there's a small enough angle between consecutive segments. 可能会起作用,但是如果连续的线段之间的角度足够小,您可能还会重叠。 Plus your sines would be uneven, so would that look good? 再加上您的罪过是不均匀的,那么看起来不错吗? Ehh... up to you. 恩...取决于你。 Or, you could dampen the offset strength to zero at the polygon transition, and then ramp it back up to 100%, but will that look good? 或者,您可以在多边形过渡处将偏移强度降低为零,然后将其渐变回100%,但这看起来不错吗? No idea, that is your call. 不知道,那是您的电话。 You could also use interpolation so that the sine waves "blend" at the transition. 您也可以使用插值法,以使正弦波在过渡时“融合”。 Will that look good? 好看 Again, no idea, still up to you. 再次,不知道,仍然取决于您。 You could even replace the offending section of polygon with something like a quadratic or cubic curve, so you always have smooth transitions along which sine offsets will "just work", but will that look good? 您甚至可以用诸如二次曲线或三次曲线之类的东西替换多边形的有问题的部分,因此您始终具有平滑的过渡,正弦偏移将沿着该过渡“起作用”,但这看起来不错吗? ...you get the idea =) ...你有主意=)

The part of this question we can answer isn't super interesting, and the part that's interesting we unfortunately cannot answer for you... 这个问题我们可以回答的部分并不是超级有趣,而不幸的是我们很抱歉无法为您回答这个有趣的部分。

We can give advice, though: I don't know what your polygon represents, but "curves" almost always work better as spines (almost, because curves can have discontinuities as well, which is the very thing you want to avoid), so if you can construct curves instead, probably worth it. 不过,我们可以提供一些建议:我不知道您的多边形代表什么,但是“曲线”几乎总是可以像刺一样工作(几乎是因为曲线也可能具有不连续性,这是您要避免的事情),因此如果您可以构造曲线,可能值得。 However, that won't solve the problem of weird overlaps when your angles are too small: 但是,如果您的角度太小,那无法解决奇怪的重叠问题:

在此处输入图片说明

You're still left with problems that can only be solved with "executive decisions" more than textbook "in this situation, do this: ..." solutions. 与教科书“在这种情况下,请执行以下操作……”解决方案相比,您仍然只能通过“执行决策”解决问题。

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

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