我已经能够在水平方向上绘制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);
}
答案 0 :(得分:1)
最简单的解决方案是旋转画布:
ctx.rotate(45*Math.PI/180);
虽然我假设您需要修复画布方向,并且您需要在数学上改变您绘制的方式?在这种情况下,这里有一大堆关于如何在逆时针旋转时绘制正弦波的数学运算:
答案 1 :(得分:0)
以下将绘制与线对齐的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;
对于执行渲染的代码,我已经使用注释扩展了代码,以便您可以阅读正在进行的操作。下面是一个更有用的版本。
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;
作为一个更有用的功能,有一些快捷方式
<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;