如何缩放贝塞尔曲线以适配屏幕上不同的起止点位置
贝塞尔控制点随起止点自适应缩放实现
我有如下所示的曲线图:
曲线图
核心需求
对可拖拽的控制点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
相关产品推荐
相关产品推荐

