Javascript 生成一组点/坐标以绘制仅给定高度和宽度的平滑抛物线(半圆)
我正在用JavaScript构建一个病人监护仪模拟器。这涉及到在HTML画布上绘制抛物线半圆。通常情况下,bezierCurveTo函数不会出现问题,但此解决方案不适用于此处,因为我需要按此处演示的方式逐像素设置曲线动画。据我所知,这将需要曲线中所有点的数组 我的问题是如何从我想要的曲线所提供的宽度和高度生成这个点数组。是否有某种特殊的命令或算法,我可以用来获得这些笛卡尔坐标。要更清楚地了解我需要什么,请参考下图 一位讲师帮我做了以下等式:y=x-t1 x t2-x。这是我创建了一个point对象的代码,请记住这是用于HTML画布的,其中0,0位于左上角:Javascript 生成一组点/坐标以绘制仅给定高度和宽度的平滑抛物线(半圆),javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,我正在用JavaScript构建一个病人监护仪模拟器。这涉及到在HTML画布上绘制抛物线半圆。通常情况下,bezierCurveTo函数不会出现问题,但此解决方案不适用于此处,因为我需要按此处演示的方式逐像素设置曲线动画。据我所知,这将需要曲线中所有点的数组 我的问题是如何从我想要的曲线所提供的宽度和高度生成这个点数组。是否有某种特殊的命令或算法,我可以用来获得这些笛卡尔坐标。要更清楚地了解我需要什么,请参考下图 一位讲师帮我做了以下等式:y=x-t1 x t2-x。这是我创建了一个point对
var y = 0;
var duration = 200;
var t1 = 0;
var t2 = duration;
var x1 = 0;
var x2 = 0;
for (i = 0; i < duration; i++) {
x1 = i;
x2 = duration - i;
var ctx = canvas.getContext("2d");
y = (x1 - t1) * (t2 - x2)
if (i < duration / 2) {
y = -y;
}
data.push(new point(y));
}
虽然这在一定程度上是基于我的理解,但这个等式不允许我只指定抛物线宽度的高度
非常感谢您提供的任何帮助在这种数学情况下,最好的做法是规范化。 也就是说,在这里,试着回到x在0和1之间的情况 如果x在[t1;t2]中
delta = (x-t1) / (t2 - t1).
现在delta进入[0;1]!!!魔力
同样,对于形状函数,使用仅在[0;1]中返回的规格化函数
您在代码中给出的示例如下:
function shape(x) { return (x<0.5) ? x*(1-x) : -x*(1-x) }
代码变得更清晰了-
for ( x = t1; x<t2; x++ ) {
var delta = (x-t1) / (t2 - t1) ;
y = amplitude * shape(delta);
// do something with (x,y)
}
请参见此处的工作jsbin:
我天真地说,监控应该只显示出现的值,因为它们出现了,不?你是说来自某种传感器吗?如果没有。这是一个模拟器,因此轨迹的高度和宽度必须手动设置。非常感谢。我会看看你的建议
![var cv = document.getElementById('cv');
var ctx = cv.getContext('2d');
ctx.fillStyle = '#C66';
// shift for all the drawings
var plotShift = {x:0, y:200 } ;
// draw between t1 and t2 with an initial y shift.
// expects an easing function i.e. a function \[0;1\] -> \[0;1\]
// yShift should be the last computed value.
// returns the last computed value to allow chaining.
function drawEasingFunction (yShift, t1, t2, amplitude, func) {
var x=0, y=0;
var duration = t2 - t1;
for (x= t1; x < t2; x++) {
// delta is a figure between 0 and 1
var delta = (x - t1) / duration;
//
y = yShift + amplitude*func(delta);
ctx.fillRect(x+plotShift.x,y+plotShift.y,2,2);
}
return y;
}
var easingFunctions = \[
function (x) { return x} , /* line */
function (x) { return x*x} , /* line */
function (x) { return Math.sqrt(x)} , /* line */
function (x) { return Math.sin(Math.PI*x/2)} , /* sin */
function (x) { return x*(1-x)} , /* that's your function */
\];
var lastY = 0;
var currentX = 0;
var length = 50;
// demo of all functions
for (; currentX < cv.width; currentX+=length) {
// take a random function
var fnIndex = Math.floor(Math.random()*easingFunctions.length) ;
var thisEasingFunction = easingFunctions\[fnIndex\];
// take some random amplitude
var amplitude = (60 + Math.random()*10);
// randomly switch the amplitude sign.
if (Math.random() > 0.5) amplitude = -amplitude;
// draw ! (and store last value)
lastY = drawEasingFunction(lastY, currentX, currentX+length, amplitude, thisEasingFunction);
}][2]