倾斜方向正弦波

时间:2017-10-12 02:16:59

标签: javascript canvas sine

我已经能够在水平方向上绘制sin波,如图像(图像链接:https://i.stack.imgur.com/RTpDY.png)和垂直方向。

现在我需要以倾斜的45°方向绘制它 任何人都可以帮助我![/ p>

脚本代码:

	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);
}

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:0)

沿着一条线绘制一个sin波

以下将绘制与线对齐的sin波。这条线可以在任何方向。

标准设置

波长将以像素为单位。要使sin波形成一个完整的周期,您需要将其输入角度旋转// I'm making up the content of this array. The question doesn't show it. var array = [ { 'id': 'name', 'class': '' }, { 'id': 'birthdate', 'class': 'datepicker' }, { 'id': 'joiningdate', 'class': 'datepicker' }, { 'id': 'something', 'class': '' } ]; function createRowForAdd(rowPos) { var tRow = []; for (var i=0, l=array.length; i<l; i++) tRow.push('<td><input type="text" id="'+array[i].id+rowPos+'" class="'+array[i].class+'" /></td>'); return '<tr>' + tRow.join('') + '</tr>'; } $('button#btnAdd').click(function() { var rowPos = $("table#tblId tbody tr").length; $("table#tblId tbody").append(createRowForAdd(rowPos)).find('tr:last input.datepicker').datepicker(); }); ,因此您需要将其转换为匹配像素波长的值。

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;

示例代码

对于执行渲染的代码,我已经使用注释扩展了代码,以便您可以阅读正在进行的操作。下面是一个更有用的版本。

&#13;
&#13;
const lineWidth = 3;
const lineCap = "round";
const lineJoin = "round";
const strokeStyle = "blue";
&#13;
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();
&#13;
canvas {
  position: absolute;
  top: 0px;
  left: 0px;
}
&#13;
&#13;
&#13;

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

&#13;
&#13;
<canvas id=canvas width=4 00 height=4 00></canvas>
&#13;
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);
&#13;
canvas {
  position: absolute;
  top: 0px;
  left: 0px;
}
&#13;
&#13;
&#13;