- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定圆 C: (O, r) 和多边形 P,如何找到覆盖 P 的 C 的最小扇区?
假设圆的半径足够大,那么主要的问题是找到扇形的初始角度和最终角度。
我试图从圆心向多边形的每个角度绘制光线,并检查光线是否与多边形重叠。但是可能有两条以上的射线只接触多边形。由于 double ,我不能依赖于根据它们的方向角选择独特的光线。所以在接触光线列表中找到最小和最大角度是没有用的。除此之外,我在选择由两个终端角创建的扇区时遇到问题,因为当由 atan2
计算时,初始角度可能大于最终角度。 .
那么找到这样一个部门的正确方法是什么?
编辑:
三个示例多边形(WKT 格式):
POLYGON((52.87404 30.85613, 42.55699 28.46292, 41.54373 24.319989, 53.57623 21.300564, 62.94891 28.46292, 49.39652 27.550071, 52.87404 30.85613))
POLYGON((52.94294 30.920592, 42.55699 28.46292, 43.61965 35.545578, 55.85037 34.862696, 59.12524 36.621547, 47.68664 39.877048, 35.69973 36.198265, 37.30512 29.196711, 31.09762 28.46292, 41.54373 24.319989, 53.57623 21.300564, 62.94891 28.46292, 49.39652 27.550071, 52.94294 30.920592))
POLYGON((52.94294 30.920592, 42.55699 28.46292, 43.61965 35.545578, 52.45594 37.266299, 59.30560 29.196711, 64.12177 33.290489, 58.81733 36.554277, 47.68664 39.877048, 35.69973 36.198265, 37.30512 29.196711, 31.09762 28.46292, 41.54373 24.319989, 53.57623 21.300564, 62.94891 28.46292, 49.39652 27.550071, 52.94294 30.920592))
所有示例的圆心和半径:
O: (45, 30)
r: 25
最佳答案
首先,我们可以将您的数据处理为点云(多边形顶点)p[i]
和一些由中心定义的圆 p0
和半径 r
.如果您的点云完全在圆内,您可以忽略半径。
我们可以利用 atan2
然而,为了避免交叉和扇区选择的问题,我们不会像往常一样扩大标准笛卡尔 BBOX 计算的最小/最大边界:
atan2
每个点的角度并记住它在数组中 a[]
a[]
a[]
中找到后续角度之间的最大距离|Pi|
顶部所以如果它更多你需要+/- 2*PI
.也处理a[]
作为循环缓冲区。//---------------------------------------------------------------------------
float p0[]={52.87404,30.856130,42.55699,28.46292,41.54373,24.319989,53.57623,21.300564,62.94891,28.46292,49.39652,27.550071,52.87404,30.85613,};
float p1[]={52.94294,30.920592,42.55699,28.46292,43.61965,35.545578,55.85037,34.862696,59.12524,36.621547,47.68664,39.877048,35.69973,36.198265,37.30512,29.196711,31.09762,28.46292,41.54373,24.319989,53.57623,21.300564,62.94891,28.46292,49.39652,27.550071,52.94294,30.920592,};
float p2[]={52.94294,30.920592,42.55699,28.46292,43.61965,35.545578,52.45594,37.266299,59.30560,29.196711,64.12177,33.290489,58.81733,36.554277,47.68664,39.877048,35.69973,36.198265,37.30512,29.196711,31.09762,28.46292,41.54373,24.319989,53.57623,21.300564,62.94891,28.46292,49.39652,27.550071,52.94294,30.920592,};
float x0=45.0,y0=30.0,R=25.0;
//---------------------------------------------------------------------------
template <class T> void sort_asc_bubble(T *a,int n)
{
int i,e; T a0,a1;
for (e=1;e;n--) // loop until no swap occurs
for (e=0,a0=a[0],a1=a[1],i=1;i<n;a0=a1,i++,a1=a[i])// proces unsorted part of array
if (a0>a1) // condition if swap needed
{ a[i-1]=a1; a[i]=a0; a1=a0; e=1; } // swap and allow to process array again
}
//---------------------------------------------------------------------------
void get_sector(float x0,float y0,float r,float *p,int n,float &a0,float &a1)
{
// x0,y0 circle center
// r circle radius
// p[n] polyline vertexes
// a0,a1 output angle range a0<=a1
int i,j,m=n>>1;
float x,y,*a;
a=new float[m];
// process points and compute angles
for (j=0,i=0;i<n;j++)
{
x=p[i]-x0; i++;
y=p[i]-y0; i++;
a[j]=atan2(y,x);
}
// sort by angle
sort_asc_bubble(a,m);
// get max distance
a0=a[m-1]; a1=a[0]; x=a1-a0;
while (x<-M_PI) x+=2.0*M_PI;
while (x>+M_PI) x-=2.0*M_PI;
if (x<0.0) x=-x;
for (j=1;j<m;j++)
{
y=a[j]-a[j-1];
while (y<-M_PI) y+=2.0*M_PI;
while (y>+M_PI) y-=2.0*M_PI;
if (y<0.0) y=-y;
if (y>x){ a0=a[j-1]; a1=a[j]; x=y; }
}
}
//---------------------------------------------------------------------------
void TMain::draw()
{
int i,n;
float x,y,r,*p,a0=0.0,a1=0.0;
float ax,ay,bx,by;
float zoom=7.0;
p=p0; n=sizeof(p0)/sizeof(p0[0]);
// p=p1; n=sizeof(p1)/sizeof(p1[0]);
// p=p2; n=sizeof(p2)/sizeof(p2[0]);
get_sector(x0,y0,R,p,n,a0,a1);
// clear buffer
bmp->Canvas->Brush->Color=clBlack;
bmp->Canvas->FillRect(TRect(0,0,xs,ys));
// circle
x=x0; y=y0; r=R;
ax=x+R*cos(a0);
ay=y+R*sin(a0);
bx=x+R*cos(a1);
by=y+R*sin(a1);
x*=zoom; y*=zoom; r*=zoom;
ax*=zoom; ay*=zoom;
bx*=zoom; by*=zoom;
bmp->Canvas->Pen->Color=clBlue;
bmp->Canvas->Brush->Color=TColor(0x00101010);
bmp->Canvas->Ellipse(x-r,y-r,x+r,y+r);
bmp->Canvas->Pen->Color=clAqua;
bmp->Canvas->Brush->Color=TColor(0x00202020);
bmp->Canvas->Pie(x-r,y-r,x+r,y+r,ax,ay,bx,by);
// PCL
r=2.0;
bmp->Canvas->Pen->Color=clAqua;
bmp->Canvas->Brush->Color=clAqua;
for (i=0;i<n;)
{
x=p[i]; i++;
y=p[i]; i++;
x*=zoom; y*=zoom;
bmp->Canvas->Ellipse(x-r,y-r,x+r,y+r);
}
// render backbuffer
Main->Canvas->Draw(0,0,bmp);
}
//---------------------------------------------------------------------------
您可以忽略
void TMain::draw()
函数只是使用示例,这是预览:
a[]
<a0,a1>
具有预定义的多边形缠绕规则(因此 CW 或 CCW 但一致)。而不是数组 a[]
您将订购间隔列表,您可以在其中插入新间隔或在重叠时与现有间隔合并。这种方法是安全的,但合并角度间隔并不那么容易。如果输入数据是折线(就像你的一样),这意味着下一行从前一行端点开始,所以你可以忽略间隔列表,只放大单个,但你仍然需要正确处理放大,这不是微不足道的。void get_sector_pol(float x0,float y0,float r,float *p,int n,float &a0,float &a1)
{
// x0,y0 circle center
// r circle radius
// p[n] point cloud
// a0,a1 output angle range a0<=a1
int i,j,k,N=10,m=(n>>1)*N;
float ax,ay,bx,by,x,y,dx,dy,*a,_N=1.0/N;
a=new float[m];
// process points and compute angles
bx=p[n-2]-x0; i++;
by=p[n-1]-y0; i++;
for (j=0,i=0;i<n;)
{
ax=bx; ay=by;
bx=p[i]-x0; i++;
by=p[i]-y0; i++;
dx=_N*(bx-ax); x=ax;
dy=_N*(by-ay); y=ay;
for (k=0;k<N;k++,x+=dx,y+=dy,j++) a[j]=atan2(y,x);
}
// sort by angle
sort_asc_bubble(a,m);
// get max distance
a0=a[m-1]; a1=a[0]; x=a1-a0;
while (x<-M_PI) x+=2.0*M_PI;
while (x>+M_PI) x-=2.0*M_PI;
if (x<0.0) x=-x;
for (j=1;j<m;j++)
{
y=a[j]-a[j-1];
while (y<-M_PI) y+=2.0*M_PI;
while (y>+M_PI) y-=2.0*M_PI;
if (y<0.0) y=-y;
if (y>x){ a0=a[j-1]; a1=a[j]; x=y; }
}
}
如您所见,它几乎相同,只是简单
DDA 添加到第一个循环 win
N
每行点数。这是仅使用点云方法失败的第二个多边形的预览:
关于c# - 如何找到覆盖多边形的圆的最小扇区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64298852/
我已经实现了 Bentley-Ottmann-algorithm检测多边形-多边形交叉点。这通常非常有效:由于多边形不自相交,因此两个多边形的线段并集中的任何线段相交表明两个多边形相交。 但是如果我看
我在 Silverlight 中有一个多边形(棋盘游戏的十六进制),例如; public class GridHex : IGridShape { ..... public IList
我创建了一个简单的 DirectX 应用程序来渲染一个顶点场。顶点呈现如下(如果从顶部查看): |\|\|\|\| |\|\|\|\| 每个三角形都是这样渲染的: 1 |\ 2 3 这应该意味着多边形
我的代码的某些部分here : var stage = new Kinetic.Stage({ container: "canvas", width: 300,
我正在尝试从 map 数据构造导航网格物体。步骤之一涉及将二进制图像(其中0表示占用空间,1表示自由空间)转换成平面直线图。 我正在尝试找到一种可靠的方法。我目前的想法是使用Canny边缘检测器,然后
我的任务是编写 MATLAB 代码来生成一个由 4 部分组成的 Logo ,如屏幕截图所示。左上角应为黑色,右下角应为白色。另一个程序应随机选择两种颜色。 我采取了以下方法: clear all cl
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
如何向 google.maps.Rectangle 和 google.maps.Polygon 添加标题? title 属性在 RectangleOptions 中不可用.我试过了,但没用(对于 go
我有一个表,用于将表上的段存储为多边形。然后我想获取所有被另一个多边形接触的线段,例如正方形或圆形。图片上:http://img.acianetmedia.com/GJ3 我将灰色小框表示为段和 bi
我正在我的网站上使用 CSS 来制作形状。它在 chrome 中运行良好,但在 mozilla、internet explorer 中打开时,它无法运行。 有人知道怎么解决吗? 这是 fiddle h
我使用 DrawingManager 在 Google map 上绘制圆形和多边形。我尝试使用下面的代码删除圆形/多边形。 selectedShape.setMap(null); 这里selected
我看到了很多如何检测碰撞的教程,但没有看到如何解决它。我正在制作一个自上而下的游戏,玩家具有圆形碰撞形状,而墙壁是各种多边形。 我正在使用 slick2d。我应该做的是,如果玩家与角落碰撞,我会按法线
我对 tkinter 比较陌生,我正在制作一个只使用正方形的游戏。我正在抄写的书只显示三角形。这是代码: # The tkinter launcher (Already complete) from
我在 OpenCV/Python 中工作,我遇到了这个问题。我已经使用 cv2.minAreaRect() 来获取围绕一组点的边界框。是否有任何其他函数/通用算法可以给我内接多边形(点集)的最大矩形?
如果给定一组线段 S ,我们能否设计一种算法来测试集合 S 中的线段是否可以形成多边形,我对它们是否相交多边形不感兴趣,我只想知道我可以测试什么标准, 任何建议 最佳答案 构建一个图形数据结构,其中节
如何从多个地理位置(经度、纬度值)创建多边形地理围栏。此外,如何在 Android 上跟踪用户进入此地理围栏区域或从该区域退出。 最佳答案 地理围栏只是一组形成多边形的纬度/经度点。获得纬度/经度点列
我想要一个 complex image like this在我的申请中。我想让用户点击复杂的多边形(在这种情况下是有边界的国家/地区)并突出显示他们点击的多边形。我有我需要用于该状态的图像。 我怎样才
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
我想在 python tkinter 中移动对象,特别是多边形。问题出在 is_click 函数中。我似乎无法弄清楚如何确定我是否单击了该对象。代码还没有 100% 完成,移动仍然需要完成,但我现在需
我有一个大多边形,我想找到与该多边形相交的要素,但由于多边形太大,我遇到超时异常。 我试图研究 JTS 方法,但不知道如何使用它。 final List coordinates = List.of(n
我是一名优秀的程序员,十分优秀!