You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何缩放贝塞尔曲线以适配屏幕上不同的起止点位置

贝塞尔控制点随起止点自适应缩放实现

我有如下所示的曲线图:
曲线图

核心需求

对可拖拽的控制点P1做坐标转换,使其能随屏幕上设置的不同曲线起止点自动缩放适配:无论曲线的起止点设置在屏幕哪个位置,曲线上的控制点都能保持相对位置不变,保证不同起止点下的曲线形态与参考图完全一致。

原有问题代码

function bezier.scale(startingPosition : Vector2, endingPosition : Vector2)
        local screenSize = workspace.CurrentCamera.ViewportSize
        local lengthX = (endingPosition.X - startingPosition.X)
        local lengthY = (endingPosition.Y - startingPosition.Y)
        
        local screenRelativeX = (screenSize.X - startingPosition.X) + lengthX
        local screenRelativeY = (screenSize.Y - startingPosition.Y) + lengthY
        local scaleX = (screenRelativeX / graphBackground.Size.X.Offset)
        local scaleY = (screenRelativeY  / graphBackground.Size.Y.Offset) 

        local x = (bezierPoint.Position.X.Offset * scaleX) 
        local y = (bezierPoint.Position.Y.Offset * scaleY) 

        return Vector2.new(x, y)
      end 

代码错误点

  • 错误引入全局屏幕尺寸参与计算,控制点相对位置只和曲线起止点构成的局部坐标系有关,和整个视口尺寸没有关联
  • 没有提前将控制点坐标转换为相对参考起点的归一化偏移值,直接用绝对坐标乘缩放比会产生固定偏移
  • 缩放计算完成后没有叠加新的起点坐标偏移,最终返回的坐标位置完全错位
  • 缩放比例的分母错误使用了背景图尺寸,应该用参考状态下曲线自身的起止点长度作为缩放基准

正确实现方案

坐标转换遵循「参考值缓存→缩放比计算→偏移叠加」的固定流程:

  • 初始化阶段缓存参考图中曲线的起点、终点坐标,以及控制点P1相对参考起点的偏移值,同时计算参考状态下曲线X、Y方向的总长度
  • 传入新的起止点时,用新方向长度除以参考方向长度,得到对应方向的缩放比
  • 将控制点的原始相对偏移乘对应缩放比,再叠加新起点的坐标,即为适配后的正确控制点位置
-- === 初始化阶段执行一次,缓存参考基准值 ===
-- 替换为参考图中曲线的实际起止点坐标
local refStartPos = Vector2.new(refStartX, refStartY)
local refEndPos = Vector2.new(refEndX, refEndY)
local refTotalX = refEndPos.X - refStartPos.X
local refTotalY = refEndPos.Y - refStartPos.Y
-- 缓存控制点P1在参考坐标系下相对起点的偏移
local p1RefOffset = Vector2.new(
    bezierPoint.Position.X.Offset - refStartPos.X,
    bezierPoint.Position.Y.Offset - refStartPos.Y
)

-- === 缩放适配函数 ===
function bezier.scale(newStart: Vector2, newEnd: Vector2)
    local newTotalX = newEnd.X - newStart.X
    local newTotalY = newEnd.Y - newStart.Y
    -- 计算两个方向的缩放比
    local scaleX = newTotalX / refTotalX
    local scaleY = newTotalY / refTotalY

    -- 缩放后叠加新起点偏移,得到最终坐标
    local finalX = newStart.X + p1RefOffset.X * scaleX
    local finalY = newStart.Y + p1RefOffset.Y * scaleY

    return Vector2.new(finalX, finalY)
end

补充:如果需要保证曲线不被拉伸变形,可以取scaleX和scaleY中较小的值作为统一缩放比,再根据对齐规则计算居中偏移即可。

内容的提问来源于stack exchange,提问作者Require

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 12:09:27