我正在使用画布进行弹丸运动模拟,我需要绘制弹丸路径(轨迹)的线。我相信最好的方法是使用quadraticCurveTo()方法绘制贝塞尔曲线来完成此任务(因为可以使用抛物线对抛射运动进行建模)。
我知道抛物线的起点和终点以及最大值,但我不确定如何计算贝塞尔曲线的控制点。
有更准确的方法来计算二次控制点,但这种近似方法的优点是计算速度非常快:
// calc a control point
var cpX = 2*anywhereOnCurveX -startX/2 -endX/2;
var cpY = 2*anywhereOnCurveY -startY/2 -endY/2;
这是一个现场演示,它在给定起点、终点和曲线上的任何点(除起点/终点之外的任何点)的情况下计算近似控制点:
要使贝塞尔曲线形成抛物线,二阶导数必须恒定。这需要:P0 - 3 * P1 = P3 - 3 * P2。
可以使用以下控制点:
P0 = (x - w, y)
P1 = (x - w/3, y + h)
P2 = (x + w/3, y + h)
P3 = (x + w, y)
用贝塞尔曲线绘制抛物线(给定 a、b、c 参数)的更准确版本(使用 Lua for Love2D 解决方案,但你可以阅读代码):
function drawBezierParabola (a, b, c, y1, y2)
-- crop points:
local x1 = (-b + math.sqrt(b^2 - 4*a*(c-y1))) / (2*a)
local x2 = (-b - math.sqrt(b^2 - 4*a*(c-y2))) / (2*a)
--[[ or by given x1 and x2:
local y1 = a * x1^2 + b * x1 + c
local y2 = a * x2^2 + b * x2 + c
]]
-- derivatives:
local k1 = 2 * a * x1 + b
local k2 = 2 * a * x2 + b
-- bezier control point:
local xi = -b/(2*a) - (y2 - y1) / (k1 - k2)
local yi = k1 * (xi - x1) + y1
local bezier = love.math.newBezierCurve (x1, y1, xi, yi, x2, y2)
love.graphics.line (bezier:render())
end