当前位置: 首页 > news >正文

Cyrus-Beck算法的计算方法

运算步骤

  1. 表示出 P ( t ) = P 0 + t ⋅ D P(t) = P_0 + t \cdot D P(t)=P0+tD,求解其中的 D = P 1 − P 0 D = P_1 - P_0 D=P1P0
  2. 计算每一条边指向多边形内部的法向量 N i N_i Ni
  3. 对每一条边都进行分组, N i ⋅ D > 0 N_i \cdot D > 0 NiD>0为Enter ( P E P_E PE),反之 N i ⋅ D < 0 N_i \cdot D < 0 NiD<0则为Exit ( P L P_L PL)
  4. 根据 t = − N i ⋅ ( P 0 − A i ) N i ⋅ D t = -\frac{N_i \cdot (P_0 - A_i)}{N_i \cdot D} t=NiDNi(P0Ai) t t t进行求解。
  5. P E P_E PE中寻找最大值,若全为负数则设为0;在 P L P_L PL中寻找最小值,若全为大于1的数则设为1。
  6. 将求到的 t e x i t t_{exit} texit t e n t e r t_{enter} tenter带入1中的式子得到裁剪的线段的起点和终点。

例题

  • 裁剪窗口:凸五边形,顶点按逆时针顺序为 A ( 2 , 1 ) A(2,1) A(2,1) B ( 4 , 2 ) B(4,2) B(4,2) C ( 5 , 4 ) C(5,4) C(5,4) D ( 3 , 5 ) D(3,5) D(3,5) E ( 1 , 3 ) E(1,3) E(1,3)
  • 待裁剪线段 P 0 ( 0 , 2 ) → P 1 ( 6 , 4 ) P_0(0,2) \to P_1(6,4) P0(0,2)P1(6,4)(从左下到右上)。

Alt

(1) 参数化线段

P ( t ) = P 0 + t ⋅ D , D = P 1 − P 0 = ( 6 , 4 ) − ( 0 , 2 ) = ( 6 , 2 ) P(t) = P_0 + t \cdot D, \\ D = P_1 - P_0 = (6, 4) - (0, 2) = (6, 2) P(t)=P0+tD,D=P1P0=(6,4)(0,2)=(6,2)

其中 t ∈ [ 0 , 1 ] t\in[0,1] t[0,1]

(2) 五边形各边的法向量(内法向)

对每条边 E i E_i Ei,计算内法向量 N i = ( E i y , − E i x ) N_i=(E_{iy},-E_{ix}) Ni=(Eiy,Eix)(垂直于边并指向内部):

  • A B AB AB:向量 B − A = ( 2 , 1 ) B-A=(2,1) BA=(2,1),法向量 N 1 = ( − 1 , 2 ) N_1=(-1,2) N1=(1,2)
  • B C BC BC:向量 C − B = ( 1 , 2 ) C-B=(1,2) CB=(1,2),法向量 N 2 = ( − 2 , 1 ) N_2=(-2,1) N2=(2,1)
  • C D CD CD:向量 D − C = ( − 2 , 1 ) D-C=(-2,1) DC=(2,1),法向量 N 3 = ( − 1 , − 2 ) N_3=(-1,-2) N3=(1,2)
  • D E DE DE:向量 E − D = ( − 2 , − 2 ) E-D=(-2,-2) ED=(2,2),法向量 N 4 = ( 2 , − 2 ) N_4=(2,-2) N4=(2,2)
  • E A EA EA:向量 A − E = ( 1 , − 2 ) A-E=(1,-2) AE=(1,2),法向量 N 5 = ( 2 , 1 ) N_5=(2,1) N5=(2,1)
(3) 计算每条边的交点参数 t t t

对每条边 E i E_i Ei,计算:
t = − N i ⋅ ( P 0 − A i ) N i ⋅ D 或 t = N i ⋅ ( A i − P 0 ) N i ⋅ D t = -\frac{N_i \cdot (P_0 - A_i)}{N_i \cdot D} \\ 或 \quad t = \frac{N_i \cdot (A_i - P_0)}{N_i \cdot D} \\ t=NiDNi(P0Ai)t=NiDNi(AiP0)
注意: A i A_i Ai 为每条边的起点。

并分类为PE(进入)PL(离开)

法向量 N i N_i Ni N i ⋅ D N_i \cdot D NiD W = P 0 − A i W=P_0-A_i W=P0Ai N i ⋅ W N_i \cdot W NiW t t t分类
AB ( − 1 , 2 ) (-1,2) (1,2) − 1 ⋅ 6 + 2 ⋅ 2 = − 2 -1 \cdot 6 + 2 \cdot 2 = -2 16+22=2 ( 0 − 2 , 2 − 1 ) = ( − 2 , 1 ) (0-2,2-1)=(-2,1) (02,21)=(2,1) − 1 ⋅ ( − 2 ) + 2 ⋅ 1 = 4 -1 \cdot (-2) + 2 \cdot 1 = 4 1(2)+21=4 t = 2 t=2 t=2PL
BC ( − 2 , 1 ) (-2,1) (2,1) − 2 ⋅ 6 + 1 ⋅ 2 = − 10 -2 \cdot 6 + 1 \cdot 2 = -10 26+12=10 ( 0 − 4 , 2 − 2 ) = ( − 4 , 0 ) (0-4,2-2)=(-4,0) (04,22)=(4,0) − 2 ⋅ ( − 4 ) + 1 ⋅ 0 = 8 -2 \cdot (-4) + 1 \cdot 0 = 8 2(4)+10=8 t = 0.8 t=0.8 t=0.8PL
CD ( − 1 , − 2 ) (-1,-2) (1,2) − 1 ⋅ 6 + ( − 2 ) ⋅ 2 = − 10 -1 \cdot 6 + (-2) \cdot 2 = -10 16+(2)2=10 ( 0 − 5 , 2 − 4 ) = ( − 5 , − 2 ) (0-5,2-4)=(-5,-2) (05,24)=(5,2) − 1 ⋅ ( − 5 ) + ( − 2 ) ⋅ ( − 2 ) = 9 -1 \cdot (-5) + (-2) \cdot (-2) = 9 1(5)+(2)(2)=9 t = 0.9 t=0.9 t=0.9PL
DE ( 2 , − 2 ) (2,-2) (2,2) 2 ⋅ 6 + ( − 2 ) ⋅ 2 = − 8 2 \cdot 6 + (-2) \cdot 2 = -8 26+(2)2=8 ( 0 − 3 , 2 − 5 ) = ( − 3 , − 3 ) (0-3,2-5)=(-3,-3) (03,25)=(3,3) 2 ⋅ ( − 3 ) + ( − 2 ) ⋅ ( − 3 ) = 0 2 \cdot (-3) + (-2) \cdot (-3) = 0 2(3)+(2)(3)=0 t = 0 t=0 t=0PE
EA ( 2 , 1 ) (2,1) (2,1) 2 ⋅ 6 + 1 ⋅ 2 = 14 2 \cdot 6 + 1 \cdot 2 = 14 26+12=14 ( 0 − 1 , 2 − 3 ) = ( − 1 , − 1 ) (0-1,2-3)=(-1,-1) (01,23)=(1,1) 2 ⋅ ( − 1 ) + 1 ⋅ ( − 1 ) = − 3 2 \cdot (-1) + 1 \cdot (-1) = -3 2(1)+1(1)=3 t = 3 14 ≈ 0.214 t = \frac{3}{14} \approx 0.214 t=1430.214PE
(4) 分类并确定 t enter t_{\text{enter}} tenter t exit t_{\text{exit}} texit
  • PE组(进入) t = 0 t=0 t=0(DE边)、 t ≈ 0.214 t\approx0.214 t0.214(EA边)。
    t enter = max ⁡ ( 0 , 0.214 ) = 0.214 t_{\text{enter}}=\max(0,0.214)=0.214 tenter=max(0,0.214)=0.214
  • PL组(离开) t = 0.8 t=0.8 t=0.8(BC边)、 t = 0.9 t=0.9 t=0.9(CD边)、 t = 2 t=2 t=2(AB边)。
    t exit = min ⁡ ( 0.8 , 0.9 , 2 ) = 0.8 t_{\text{exit}}=\min(0.8,0.9,2)=0.8 texit=min(0.8,0.9,2)=0.8
(5) 裁剪结果
  • 因为 t enter = 0.214 ≤ t exit = 0.8 t_{\text{enter}}=0.214 \leq t_{\text{exit}}=0.8 tenter=0.214texit=0.8,线段部分可见。
  • 可见部分
    P ( 0.214 ) = ( 0 + 0.214 × 6 , 2 + 0.214 × 2 ) ≈ ( 1.28 , 2.43 ) P(0.214)=(0+0.214 \times 6, 2+0.214\times2)\approx(1.28,2.43) P(0.214)=(0+0.214×6,2+0.214×2)(1.28,2.43)
    P ( 0.8 ) = ( 0 + 0.8 × 6 , 2 + 0.8 × 2 ) = ( 4.8 , 3.6 ) P(0.8)=(0+0.8 \times 6, 2+0.8\times2)=(4.8,3.6) P(0.8)=(0+0.8×6,2+0.8×2)=(4.8,3.6)
  • 裁剪后线段 ( 1.28 , 2.43 ) → ( 4.8 , 3.6 ) (1.28,2.43)\to(4.8,3.6) (1.28,2.43)(4.8,3.6)
http://www.xdnf.cn/news/416683.html

相关文章:

  • C++类的继承和派生
  • MYSQL事务原理分析(三)
  • 动作识别笔记
  • Linux 详解inode
  • 密码学--希尔密码
  • 电子电器架构 --- 借力第五代架构,驱动汽车产业创新引擎
  • Ansible内置模块之 group
  • vue3+vite 自动导入文件夹下所有路由
  • 【Python算法】最长递增子序列
  • python与nodejs哪个性能高
  • 1688平台开放接口实战:如何通过API获取店铺所有商品数据(Python示例)‌
  • 从PNG到矢量图:星云智控Logo的商用矢量转换全解析-优雅草卓伊凡
  • 三、transformers基础组件之Model
  • Java中进阶并发编程
  • 手撕算法(定制整理版2)
  • Day 15
  • 魔搭社区(modelscope)和huggingface下载模型到本地的方法
  • CSRF记录
  • 信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(十八)
  • 【PmHub后端篇】Redis分布式锁:保障PmHub流程状态更新的关键
  • csdn博客打赏功能
  • 加固python文件
  • 什么是 NoSQL 数据库?它与关系型数据库 (RDBMS) 的主要区别是什么?
  • (六)毛子整洁架构(测试)
  • 软件测试——开发模型
  • 杭州电商全平台代运营领军者——品融电商
  • 企业数字化中台建设方案(AI/技术中台、数据中台、业务中台)
  • 【Linux】基础I/O文件——文件描述符的引入
  • switch能否作用在byte上,long上,string上
  • 小皮面板从未授权到RCE