0

0

如何构造经过三个指定点的三次贝塞尔曲线(含水平端点约束)

聖光之護

聖光之護

发布时间:2026-02-11 10:13:40

|

259人浏览过

|

来源于php中文网

原创

如何构造经过三个指定点的三次贝塞尔曲线(含水平端点约束)

本文介绍一种数学方法,通过合理设置控制点,构造一条经过起点 P₀、终点 P₃ 和中间指定点 C 的三次贝塞尔曲线,并确保终点处切线近似水平,适用于 SVG 绘图、UI 动画及路径拟合等场景。

在矢量图形与交互设计中,标准的三次贝塞尔曲线由四个点定义:起点 $P_0$、终点 $P_3$ 和两个控制点 $P_1$、$P_2$。其参数方程为:

$$ B(t) = (1-t)^3 P_0 + 3(1-t)^2 t P_1 + 3(1-t) t^2 P_2 + t^3 P_3,\quad t \in [0,1] $$

当需求明确要求曲线必须经过三个给定点(如 $P_0$、$C$、$P_3$),且对端点方向有几何约束(例如“终点处近似水平”),则需反解控制点——这不再是自由拖拽问题,而是一个带约束的插值问题。

关键约束建模

设已知:

  • $P_0 = (x_0, y_0)$(左上)
  • $P_3 = (x_3, y_3)$(右下)
  • $C = (x_c, y_c)$(用户可拖动的中间点,曲线必须穿过它)

并附加终点水平切线约束:即 $B'(1) \parallel \text{x-axis}$,等价于 $B'_y(1) = 0$。
由导数公式: $$ B'(t) = 3(1-t)^2(P_1 - P_0) + 6(1-t)t(P_2 - P_1) + 3t^2(P_3 - P_2) $$ 代入 $t = 1$ 得: $$ B'(1) = 3(P_3 - P_2) \quad \Rightarrow \quad P_2 = (x_3,\; y_3) \text{ 或 } P_2 = (x_2,\; y_3) $$ 即:为满足终点水平,$P_2$ 必须与 $P_3$ 等高($y_2 = y_3$)。你先前将 $P_2$ 设为 $(x_0, y_3)$ 是一种启发式尝试,但并非最优;更稳健的做法是令 $P_2 = (x_2, y_3)$,保留 $x_2$ 为待定变量。

此时未知量为 $P_1 = (x_1, y_1)$ 和 $P_2 = (x_2, y_3)$,共 3 个自由度($x_1,y_1,x_2$)。我们已有:

Zeemo
Zeemo

提供视频字幕、字幕制作和字幕翻译服务

下载
  • 曲线过 $C$:$\exists\, t_c \in (0,1),\ B(t_c) = C$ → 提供 2 个方程(x/y 分量)
  • 终点水平:$y_2 = y_3$ → 已用于设定 $P_2$,不新增未知量

因此还需一个合理假设来闭合系统。常见做法是固定参数位置:令 $C$ 对应曲线中点参数 $t_c = 0.5$(实践中效果稳定,且便于解析求解)。代入 $t = 0.5$ 得:

$$ B(0.5) = \frac{1}{8}P_0 + \frac{3}{8}P_1 + \frac{3}{8}P_2 + \frac{1}{8}P_3 = C $$

整理得: $$ 3P_1 + 3P_2 = 8C - P_0 - P_3 $$

将 $P_2 = (x_2, y_3)$ 代入,分离坐标:

  • $x$ 方向:$3x_1 + 3x_2 = 8x_c - x_0 - x_3$
  • $y$ 方向:$3y_1 + 3y_3 = 8y_c - y_0 - y_3 \ \Rightarrow \ y_1 = \dfrac{8y_c - y_0 - 4y_3}{3}$

此时 $y_1$ 直接解出;$x_1$ 与 $x_2$ 仍耦合。为唯一确定,可进一步施加起点切线约束(如“起点垂直”或“自然延伸”),但若仅需灵活交互,推荐将 $x_2$ 设为 $x_3$(即 $P_2 = P_3$),退化为二次曲线;或更优地——将 $P_2$ 水平偏移固定比例,例如:

// 推荐实践:基于 P0→P3 向量设定 P2,兼顾水平性与形状可控性
const dx = x3 - x0;
const dy = y3 - y0;
const P2 = { x: x3 - 0.3 * dx, y: y3 }; // 水平回撤30%作为默认P2.x
const y1 = (8 * yc - y0 - 4 * y3) / 3;
const x1 = ((8 * xc - x0 - x3) / 3) - P2.x; // 由x方向方程反推
const P1 = { x: x1, y: y1 };

完整实现示例(JavaScript)

function cubicThroughThreePoints(P0, C, P3) {
  const { x: x0, y: y0 } = P0;
  const { x: xc, y: yc } = C;
  const { x: x3, y: y3 } = P3;

  // Step 1: Enforce horizontal tangent at P3 → P2.y = y3
  // Use heuristic: P2.x = x3 - 0.35 * (x3 - x0) for natural curvature
  const P2 = {
    x: x3 - 0.35 * (x3 - x0),
    y: y3
  };

  // Step 2: Solve for P1 using B(0.5) = C
  const y1 = (8 * yc - y0 - 4 * y3) / 3;
  const x1 = (8 * xc - x0 - x3) / 3 - P2.x;

  return {
    P0,
    P1: { x: x1, y: y1 },
    P2,
    P3
  };
}

// Usage:
const curve = cubicThroughThreePoints(
  {x: 50, y: 50},   // P0 (top-left)
  {x: 120, y: 100}, // C (user-draggable)
  {x: 200, y: 180}  // P3 (bottom-right)
);
console.log(curve); 
// → { P0, P1: {x: ..., y: ...}, P2: {x: ..., y: 180}, P3 }

注意事项与优化建议

  • 参数 $t_c = 0.5$ 是实用折衷:严格过三点需数值求解(如牛顿法),但 $t=0.5$ 在多数 UI 场景下视觉误差可忽略,且保证解析可解;
  • ⚠️ 避免退化:若 $C$ 过于靠近 $P_0$ 或 $P_3$,可能导致 $P_1$ 或 $P_2$ 偏离预期区域,建议对输入做边界检查(如 $t_c \in [0.25, 0.75]$);
  • ? SVG 应用提示:将结果传入 path d="M x0 y0 C x1 y1, x2 y2, x3 y3" 即可渲染;
  • ? 交互增强:可将 $P_2.x$ 设为可调参数(如滑块),实现“曲率调节”,比直接拖动 $P_1$ 更符合直觉。

该方法已在 SolidJS、D3 和 Canvas 项目中验证有效(参考 Codesandbox 实例),兼顾数学严谨性与工程可用性。

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
html5动画制作有哪些制作方法
html5动画制作有哪些制作方法

html5动画制作方法有使用CSS3动画、使用JavaScript动画库、使用HTML5 Canvas等。想了解更多html5动画制作方法相关内容,可以阅读本专题下面的文章。

520

2023.10.23

包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法
包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法

本专题汇总了包子漫画官网和网页版入口,提供最新章节抢先看方法、正版免费阅读指南,以及稳定访问方式,帮助用户快速直达包子漫画页面,无广告畅享全集漫画内容。

132

2026.02.10

MC.JS网页版快速畅玩指南_MC.JS官网在线入口及免安装体验方法
MC.JS网页版快速畅玩指南_MC.JS官网在线入口及免安装体验方法

本专题汇总了MC.JS官网入口和网页版快速畅玩方法,提供免安装访问、不同版本(1.8.8、1.12.8)在线体验指南,以及正版网页端操作说明,帮助玩家轻松进入MC.JS世界,实现即时畅玩与高效体验。

80

2026.02.10

谷歌邮箱网页版登录与注册全指南_Gmail账号快速访问与安全操作教程
谷歌邮箱网页版登录与注册全指南_Gmail账号快速访问与安全操作教程

本专题汇总了谷歌邮箱网页版的最新登录入口和注册方法,详细提供官方账号快速访问方式、网页版操作教程及安全登录技巧,帮助用户轻松管理Gmail邮箱账户,实现高效、安全的邮箱使用体验。

44

2026.02.10

铁路12306订票与退改全攻略_高效购票与座位选取技巧
铁路12306订票与退改全攻略_高效购票与座位选取技巧

本专题全面汇总铁路12306订票、退票、改签及候补订单操作技巧,提供车厢座位分布参考、抢票攻略和高铁安检注意事项,帮助新手用户快速掌握高效购票与退改流程,提高出行效率和体验。

75

2026.02.10

TensorFlow2深度学习模型实战与优化
TensorFlow2深度学习模型实战与优化

本专题面向 AI 与数据科学开发者,系统讲解 TensorFlow 2 框架下深度学习模型的构建、训练、调优与部署。内容包括神经网络基础、卷积神经网络、循环神经网络、优化算法及模型性能提升技巧。通过实战项目演示,帮助开发者掌握从模型设计到上线的完整流程。

1

2026.02.10

Vue3组合式API与组件开发实战
Vue3组合式API与组件开发实战

本专题讲解 Vue 3 组合式 API 的核心概念与应用技巧,深入分析响应式系统、生命周期管理、组件设计与复用策略。通过完整项目案例,指导前端开发者实现高性能、结构清晰的 Vue 应用,提升开发效率与代码可维护性。

13

2026.02.10

Go语言微服务架构与gRPC实战
Go语言微服务架构与gRPC实战

本专题面向有 Go 基础的开发者,系统讲解微服务架构设计与 gRPC 的高效应用。内容涵盖服务拆分、RPC 通信、负载均衡、错误处理、服务注册与发现等关键技术。通过实战案例,帮助开发者搭建高性能、可扩展的 Go 微服务系统。

1

2026.02.10

React 18状态管理与Hooks高级实践
React 18状态管理与Hooks高级实践

本专题专注于 React 18 的高级开发技术,详细讲解 useState、useEffect、useReducer、useContext 等 Hooks 的使用技巧,以及 Redux、Zustand 等状态管理工具的集成与优化方法。通过真实案例,帮助前端开发者构建可维护、性能优良的现代 React 应用。

6

2026.02.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号