使用 JavaScript Canvas 绘制方程式:y = log(29.565ln(x) - 4.4898)

Plotting an Equation Using JavaScript Canvas: y = log(29.565ln(x) - 4.4898)

提问人:Fabr 提问时间:11/17/2023 最后编辑:Amit MohantyFabr 更新时间:11/21/2023 访问量:39

问:

我正在尝试在 JavaScript 画布上绘制方程式。挑战在于确定三次贝塞尔曲线的控制点,该曲线准确表示指定起点和终点之间的方程。我的起始 x 是 1.64003,起始 y 是 -4.07205084,结束 x 是 4,结束 y 是 1.562245182。y = log(29.565ln(x) - 4.4898)

我探索了各种方法,包括使用三次贝塞尔曲线和尝试使用伯恩斯坦多项式进行插值。但是,这些方法尚未为曲线生成准确的临界点或控制点。

此外,我还考虑过找到最大曲率点以将曲线分成两个二次贝塞尔的想法,但我无法设计一个准确确定该点的程序。maxCurv

这里有两个片段展示了我的尝试:

我正在寻找指导或替代方法,以便在 JavaScript 画布上准确绘制此方程,确保绘制的曲线与指定起点和终点之间的函数行为紧密一致。任何实现这一目标的见解、方法或策略将不胜感激。谢谢!

JavaScript 绘图 塞尔 样条曲线

评论


答:

1赞 Mike 'Pomax' Kamermans 11/18/2023 #1

只需通过在画布上绘制路径来绘制函数即可。无需近似:

// Get the graphics context and flip the coordinate
// system so that (0,0) is in the lower-left:
const ctx = graph.getContext(`2d`);
graph.width = graph.height = 400;
ctx.translate(0,graph.height);
ctx.scale(1,-1);

// JS's Math.log is the natural logaritm
const { log: ln, min, max } = Math;

// then again, we can make any log function
// using any other log, so log10 is:
const log = v => ln(v)/ln(10);

// Let's write a simple plot2D function so
// that we can easily plot anything we want:
function plot2D(f, start=0, end=1) {
  // we'll generate values along the entire canvas' width:
  const interval = end - start;
  const step = interval / graph.width;
  const points = [...new Array(graph.width)].map((_,x) => f(start + x*step));

  // To plot this in a way to "looks good" we'll want
  // to scale everything so that it fills the canvas:
  const minValue = min(...points);
  const maxValue = max(...points);
  const range = maxValue - minValue;
  const scaleY = graph.height / range;
  const yValues = points.map((value) => (value - minValue) * scaleY);
 
  // And then we just draw a path using moveTo and lineTo:
  ctx.beginPath();
  ctx.moveTo(0, yValues[0]);
  for(let x=1; x<yValues.length; x++) ctx.lineTo(x, yValues[x]);
  ctx.stroke();
}

// Then, your function:
const ourFunction = (x) => log(29.565 * ln(x) - 4.4898);

// And then we plot that:
plot2D(ourFunction, 1.64003, 4);
canvas {
  border: 1px solid black;
  background: #EEE;
}
<canvas id="graph" width"500px" height="500px"></canvas>

(我将保留填充画布,添加和标记轴,并沿这些轴放置正确的单位值供您执行)

但请注意,您声称“我的起始 x 是 1.64003,起始 y 是 -4.07205084,结束 x 是 4,结束 y 是 1.562245182”的说法是不正确的:假设这是以 10 为底的对数函数并且是以 E 为底的对数,这些不是您将获得这些值的值。您将从 开始,到 结束。loglnyxy=1.0058852487205416y=1.5617255645804091