角度方向正弦波

angled direction sine wave

我已经能够在水平方向绘制正弦波,如图所示(图像link:https://i.stack.imgur.com/RTpDY.png)和垂直方向。

现在我需要在一个45°角的方向上绘制它 谁能帮帮我!

脚本代码:

 var c =document.getElementById("c");
 var ctx=c.getContext('2d');
 var x=0,y=250,vx=0.05,vy=0.05,a=1;
for(var i=0; i<501;i++){
    x += a;
    y = Math.floor(500 * (0.5 - 0.15 * Math.sin(vy)));
    vy += vx;
    // this.ctx.clearRect(0, 0, 500,500);
    this.ctx.beginPath();
    this.ctx.arc(x, y, 2, 0, Math.PI * 2, true);
    this.ctx.closePath();
    this.ctx.fillStyle = 'red';
    this.ctx.fill();
    console.log("x:"+x+"y:"+y+"vy:"+vy);
}

最简单的解决方案是旋转 canvas:

ctx.rotate(45*Math.PI/180);  

虽然我假设您需要固定 canvas 方向并且您需要从数学上改变您的绘制方式?在这种情况下,这里有一大堆关于如何在逆时针旋转时绘制正弦波的数学:

http://mathman.biz/html/rotatingsine.html

沿直线绘制正弦波

下面将绘制一条与直线对齐的正弦波。直线可以是任意方向。

标准设置

波长将以像素为单位。为了使正弦波形成一个完整的周期,您需要将其输入角度旋转 Math.PI * 2,因此您需要将其转换为与像素波长匹配的值。

const waveLen = 400; // pixels

正弦波的相位是从波的哪一部分开始的,因为波长以像素为单位,相位也是以像素为单位,表示沿波的距离,表示起始角。

const phase = 200; // mid way

波的振幅是波的最大点和最小点在中心线上方和下方的距离。这又是像素

const amplitude = 100;

波也有一个偏移量,虽然在这种情况下不是很重要,但我也会添加它。也以像素为单位

const offset = 0;

标记波浪中心的线有开始和结束坐标

const x1 = 20;
const y1 = 20;
const x2 = 400;
const y2 = 400;

以及一些上下文设置

const lineWidth = 3;
const lineCap = "round";
const lineJoin = "round";
const strokeStyle = "blue";

示例代码

因此,对于执行渲染的代码,我用注释扩展了代码,以便您可以阅读正在发生的事情。下面是一个更好用的版本。

const ctx = canvas.getContext("2d");
canvas.width = innerWidth;
canvas.height = innerHeight;

window.addEventListener("resize", () => {
  canvas.width = innerWidth;
  canvas.height = innerHeight;
  y2 = x2 = innerWidth; // at 45 deg
  drawSinWave();
})

const waveLen = 120; // pixels
const phase = 50; // mid way
const amplitude = 25;
const offset = 0;
const x1 = 20;
const y1 = 20;
var x2 = 400; // as vars to let it change to fit resize
var y2 = 400;



function drawSinWave() {

  ctx.lineWidth = 3;
  ctx.lineCap = "round";
  ctx.lineJoin = "round";
  ctx.strokeStyle = "blue";

  // get the vector form of the line
  const vx = x2 - x1;
  const vy = y2 - y1;

  // Get the length of the line in pixels
  const dist = Math.sqrt(vx * vx + vy * vy);

  // Make the vector one pixel long to move along the line
  const px = vx / dist;
  const py = vy / dist;

  // We also need a vector to move out from the line (at 90 deg to the ine)
  // So rotate the pixel vector 90deg CW
  const ax = -py; // a for amplitude vector
  const ay = px;


  // Begin the path
  ctx.beginPath();

  // Now loop along every pixel in the line
  // We go past the end a bit as floating point errors can cause it to end
  // a pixels too early
  for (var i = 0; i <= dist + 0.5; i++) {
    // fix i if past end
    if (i > dist) {
      i = dist
    } // Carefull dont mess with this ot it will block the page

    // Use the distance to get the current angle of the wave
    // based on the wave length and phase
    const ang = ((i + phase) / waveLen) * Math.PI * 2;

    // and at this position get sin
    const val = Math.sin(ang);

    // Scale to match the amplitude and move to offset
    // as the distance from the center of the line
    const amp = val * amplitude + offset;

    // Get line ceneter at distance i using the pixel vector
    var x = x1 + px * i;
    var y = y1 + py * i;

    // Use the amp vector to move away from the line at 90 degree
    x += ax * amp;
    y += ay * amp;

    // Now add the point 
    ctx.lineTo(x, y);
  }
  ctx.stroke();
}

drawSinWave();
canvas {
  position: absolute;
  top: 0px;
  left: 0px;
}
<canvas id=canvas width=4 00 height=4 00></canvas>

作为一个更有用的功能,有一些快捷方式

const ctx = canvas.getContext("2d");
canvas.width = innerWidth;
canvas.height = innerHeight;

window.addEventListener("resize", () => {
  canvas.width = innerWidth;
  canvas.height = innerHeight;
  waveExample.y2 = waveExample.x2 = innerWidth; // at 45 deg
  drawSinWave(waveExample);
})

const waveExample = {
  waveLen: 100, // pixels
  phase: 50, // mid way
  amplitude: 35,
  offset: 0,
  x1: 20,
  y1: 20,
  x2: 400, // as vars to let it change to fit resize
  y2: 400,
  lineWidth : 5,
  lineCap : "round",
  lineJoin : "round",
  strokeStyle : "Red",
}



function drawSinWave(wave) {

  ctx.lineWidth = wave.lineWidth;
  ctx.lineCap = wave.lineCap;
  ctx.lineJoin = wave.lineJoin;
  ctx.strokeStyle = wave.strokeStyle;
  var vx = wave.x2 - wave.x1;
  var vy = wave.y2 - wave.y1;
  const dist = Math.sqrt(vx * vx + vy * vy);
  vx /= dist;
  vy /= dist;
  ctx.beginPath();
  for (var i = 0; i <= dist + 0.5; i++) {
    if (i > dist) { i = dist } 
    const pos = Math.sin(((i + wave.phase) / wave.waveLen) * Math.PI * 2) * wave.amplitude + wave.offset;
    ctx.lineTo(
      wave.x1 + vx * i - vy * pos,
      wave.y1 + vy * i + vx * pos
    );

  }
  ctx.stroke();
}


drawSinWave(waveExample);
canvas {
  position: absolute;
  top: 0px;
  left: 0px;
}
<canvas id=canvas width=4 00 height=4 00></canvas>