当前位置: 首页 > 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)

相关文章:

  • map常用接口及模拟实现
  • python标准库--collections - 高性能数据结构在算法比赛的应用
  • 机器学习第七讲:概率统计 → 预测可能性,下雨概率70%就是典型应用
  • 学习黑客Windows 病毒与威胁防护
  • MySQL全量、增量与恢复
  • wordcount在mapreduce的例子
  • 荣耀手机,系统MagicOS 9.0 USB配置没有音频来源后无法被adb检测到,无法真机调试的解决办法
  • android setImageResource和setBackgroundResource区别
  • 小红书代运营服务商综合排名分析
  • MiniCPM-V
  • 无线定位之 三 SX1302 网关源码 thread_gps 线程详解
  • SQL:JOIN 进阶
  • Tenacity 高级使用指南:Python 重试机制的终极解决方案
  • 学习日志04 java
  • MYSQL之表的约束
  • Redis 中常见的数据类型有哪些?
  • 深度强化学习有什么学习建议吗?
  • telnetlib源码深入解析
  • FanControl(电脑风扇转速控制软件) v224 中文版
  • python学习打卡day23
  • 第四届长三角国际应急博览会开幕,超3000件前沿装备技术亮相
  • 特朗普访中东绕行以色列,专家:凸显美以利益分歧扩大
  • 福建宁德市长张永宁拟任设区市党委正职,曾获评全国优秀县委书记
  • 外交部:中方期待印巴巩固和延续停火势头,避免冲突再起
  • 上海建筑领域绿色发展2025年工作要点发布
  • 撤制镇如何突破困境?欢迎订阅《澎湃城市报告》第23期