我有一个我想渲染的截断椭圆。切割部分由与另一个椭圆的交点完成(想象另一个椭圆阻挡原始椭圆)。
参考下面的2个椭圆,其中t1,t2表示参数t1,t2表示我跟踪椭圆,给出点p1,p2。
如何使用数据结构捕获空的部分?我的初始伪代码是这样的:
for(t = 0 to 360 degrees)
{
if(point_t intersects with ellipse)
{
if(P1 is not set) set t corresponding to P1 as start_t;
else set t corresponding to P2 as end_t
}
}
然后“截止”区域将由start_t <= t <= end_t
给出。
但是,此代码仅适用于第一个图表。在第二个图中,由于“截止”区域对于该范围不连续,因为实际截止区域将表示为
0 <= t <= P1 && P2 <= t <= 360 degrees
。
我应该如何编写算法来解决所有这些情况?我需要一个精确的定义(例如切断部分的t值范围),因为我需要使用这个值来解决这些截止椭圆的进一步线交叉问题。
答案 0 :(得分:2)
如果不是真的话,你的图像意味着轴对齐的椭圆在OP
中指定它两个椭圆的交集可以创建
交叉点
x0+a0*cos(t0)=x1*a1*cos(t1)
y0+b0*sin(t0)=y1*b1*sin(t1)
x0,y0
为中心,a0,b0
为半轴,t0
为第一个椭圆的参数x1,y1
为中心,a1,b1
为半轴,t1
为第二个椭圆的参数要存储哪些信息?
你可以忽略0,1分案件
2分是最简单的情况
ang0,ang1
位于ang0<ang1
ang0+0.01*(ang0+ang1)
是否在第二个椭圆内ang0
是差距的开始,ang1
结束for(t=0 ;t<=ang0 ;t+=step)...
for(t=ang1;t<=360deg;t+=step)...
for(t=ang0;t<=ang1 ;t+=step)...
3分案例很少
dang=0.01*min(|ang1-ang0|,|ang2-ang0|,|ang2-ang1|)
ang? +/- dang
在交叉点之外的触摸点4分案例
dang=0.01*min(|ang1-ang0|,|ang2-ang0|,|ang3-ang0|,...)
ang0
是否是差距ang0-ang1
for(t=0 ;t<=ang0 ;t+=step)...
for(t=ang1;t<=ang2 ;t+=step)...
for(t=ang3;t<=360deg;t+=step)...
for(t=ang0;t<=ang1 ;t+=step)...
for(t=ang2;t<=ang3 ;t+=step)...
相同的省略号
统一
(start,end)
角度为...... [注释]
dang
可以是足够小的角度步长(必须小于最小间隙)但如果太小那么你的交叉计算可以给出误报 渲染时应处理结束角度交叉,例如
for (t=ang0;t<=ang1;t+=step)
{
if (t>=ang1) { t=ang1; e=1; } else e=0;
...
if (e) break
}
x,y
是否在轴对齐的椭圆x0,y0,a,b
内?(x0,y0)
转换为(0,0)
(x-x0,y-y0)
内的0,0,a,b
点?ang=atan2(y-y0,x-x0);
if ((x-x0<=a*cos(ang))&&(y-y0<=a*sin(ang))) is_inside else is_outside;
答案 1 :(得分:0)
由于两个椭圆可能最多交叉4次(因此无论如何都会产生两个截止区域),我建议您按照建议运行代码,但将所有结果区间存储在列表中。 / p>
含义:
if(point_t intersects with ellipse)
为true
的第一个值存储为第一个间隔的起始值。继续,直到if(point_t intersects with ellipse)
为false并将其设置为结束参数。然后重复一遍。
结果是一个开始/结束值列表,您可以在其中进行迭代以进行进一步计算。此外,如果您需要每个间隔的长度,您可以在事件以0开头的情况下修改列表,以便将例如{340,20}
存储为交叉间隔。
答案 2 :(得分:0)
假设您只需要描述一个截止间隔,我建议使用(Begin,Extent)表示而不是(Begin,End)。 Extent参数是0°到360°范围内的值,对角度的跳跃不敏感。您甚至可以为其指定一个符号,以区分顺时针和逆时针遍历。
如果要描述一系列弧,也可以使用类似的技巧:您可以为每个弧提供(Begin,Extent)信息,或者包含交替的(Begin,Extent,Extent,Extent ...)边界/排除弧。