C# 确定不完整椭圆开口的代码
我有一个要渲染的截止椭圆。切割部分是通过与另一个椭圆相交来完成的(想象另一个椭圆挡住了原始椭圆) 参考下面的2个椭圆,其中t1,t2代表参数t1,t2,我画出椭圆,给出点p1,p2 如何使用数据结构捕获空的部分?我最初的伪代码是这样的:C# 确定不完整椭圆开口的代码,c#,algorithm,C#,Algorithm,我有一个要渲染的截止椭圆。切割部分是通过与另一个椭圆相交来完成的(想象另一个椭圆挡住了原始椭圆) 参考下面的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 s
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给出。您的图像暗示轴对齐的椭圆,如果不正确,请在OP中指定它
两个椭圆的交点可以创建
- 如果完全在内部/外部,则切断0
- 1如果在单侧相交,则切断
- 如果在两条边上相交,则为2条截止线
- 完全截止是两个椭圆相同
交点
- 您需要获得所有交点
- 所以要么用代数/数值方法求解它
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
为第二个椭圆的参数
- 或者将问题转化为直线的交点
- 以恒定角度扫掠布斯椭圆
- 将每个椭圆变换为凸多边形
- 点越多,得到的交点越精确
- 如果两条线相互交叉,则选择其公共部分的中点
存储什么信息
- 在开始-结束形式中,需要间隙或其他间隙的参数对
- 所以,对于每个交点,您需要确定它是间隙的起点还是终点
- 因此,您应该有一个最多4个点/角度的交点参数列表(按角度排序)
在某些情况下,您可以忽略0,1分
2分是最简单的情况
- 所以你有交角
ang0,ang1
其中ang0,因为两个椭圆可能相交4次(因此无论如何会产生两个截止区域),我建议你像你建议的那样运行代码,但将所有结果间隔存储在一个列表中
意思是:
if(点与椭圆相交)
为true
的第一个值存储为第一个间隔的起始值。如果(点与椭圆相交)
为false并将其设置为结束参数,则继续操作,直到。然后重复
结果是一个开始/结束值列表,您可以对其进行迭代以进行进一步计算。此外,如果您需要每个间隔的长度,您可以在间隔以0开始时修改列表,以将例如{340,20}
存储为交叉点间隔 假设您只需要描述一个截止时间间隔,我建议使用(Begin,Extent)表示法,而不是(Begin,End)。“范围”参数是一个范围为0°到360°的值,它对角度的跳跃不敏感。您甚至可以为其指定一个符号,以便区分顺时针和逆时针的遍历
如果您想描述一系列圆弧,也可以使用类似的技巧:您可以为每个圆弧提供(开始,范围)信息,或者为交替包含/排除的圆弧提供(开始,范围,范围…)边界。冒着看起来很傻的风险,我是否可以建议检查椭圆在t=0时是否连续?如果不检查P1实际开始的位置,并将起点从0转换为P1,终点转换为360+P1。感谢您的回复,但在这种情况下,该区域不是P1->P1+360度的整个圆吗?是的。这不是代码的目的吗?我不知道检测两个相交椭圆的逻辑,但是你的第一条线(for loop)告诉我你想在一个0到360的圆上循环。我不完全清楚遮挡的确切定义。当然,您还没有提到用于渲染的API。但我所知道的所有受C#支持的GUI API都包括使用某种类型的区域/形状进行剪裁。假设这是一个严格的渲染问题,您应该能够在渲染期间从剪辑区域中排除遮挡渲染椭圆的椭圆,并实现所需的效果。如果你能提供更多关于环境的细节,你可以给出一个真实的、详细的答案。我的理解是,虽然精确的解决方案是不可行的,但应该可以编写合理的代码,用数字方式解决这个方程。以下是一些看起来很有用的链接:,,如果你的问题是如何用另一个椭圆剪裁椭圆,请重新措辞。
for (t=ang0;t<=ang1;t+=step)
{
if (t>=ang1) { t=ang1; e=1; } else e=0;
...
if (e) break
}