计算正多边形顶点的坐标

我正在编写一个程序,我需要绘制任意数量边的多边形,每个边都由一个动态变化的给定公式进行翻译。 有一些相当有趣的数学,但我被困在这个问题上。

如何只计算边 ,并且理想地(但不是必须)将原点放在中心,我如何计算正多边形(一个所有角度相等的顶点)顶点的坐标?

例如:六边形可能有以下几点(都是float ):

 ( 1.5 , 0.5 *Math.Sqrt(3) ) ( 0 , 1 *Math.Sqrt(3) ) (-1.5 , 0.5 *Math.Sqrt(3) ) (-1.5 , -0.5 *Math.Sqrt(3) ) ( 0 , -1 *Math.Sqrt(3) ) ( 1.5 , -0.5 *Math.Sqrt(3) ) 

我的方法看起来像这样:

 void InitPolygonVertexCoords(RegularPolygon poly) 

并且需要将坐标添加到此(或类似的东西,如列表):

 Point[] _polygonVertexPoints; 

我主要对这里的算法感兴趣,但C#中的例子会很有用。 我甚至不知道从哪里开始。 我该如何实施呢? 它甚至可能吗?!

谢谢。

 for (i = 0; i < n; i++) { printf("%f %f\n",r * Math.cos(2 * Math.PI * i / n), r * Math.sin(2 * Math.PI * i / n)); } 

其中r是环绕圆的半径。 抱歉错误的语言No Habla C#。

基本上任意两个顶点之间的角度是2 pi / n,并且所有顶点都与原点相距r

编辑:如果你想让中心不是原点,请说(x,y)

 for (i = 0; i < n; i++) { printf("%f %f\n",x + r * Math.cos(2 * Math.PI * i / n), y + r * Math.sin(2 * Math.PI * i / n)); } 

点数等于边数。

你需要的angle = 2 * pi / numPointsangle = 2 * pi / numPoints

然后从原点垂直上方开始,多边形的大小由radius给出:

 for (int i = 0; i < numPoints; i++) { x = centreX + radius * sin(i * angle); y = centreY + radius * cos(i * angle); } 

如果您的中心是原点,那么只需忽略centreXcentreY条款,因为它们将是0,0。

交换cossin将使第一个点水平指向原点的右侧。

对不起,我现在手头没有完整的解决方案,但您应该尝试寻找2D渲染圈子。 圆(x,y,r)的所有经典实现都使用像您描述的绘制多边形(但有50多个边)。

假设顶点到原点的距离为1.并且说(1,0)始终是多边形的坐标。

给定顶点的数量(比如n),将(1,0)定位到下一个坐标所需的旋转角度将是(360 / n)。

这里所需的计算是旋转坐标。 这是它的本质; 旋转矩阵 。

比如theta = 360 / n;

 [cos(theta) -sin(theta)] [sin(theta) cos(theta)] 

将是你的旋转矩阵。

如果你知道线性代数,你就已经知道了我的意思。 如果不只是看看Matrix Multiplication

嗯,如果你测试这里列出的所有版本,你会发现实现不好。 你可以检查从中心到多边形的每个生成点的距离: http : //www.movable-type.co.uk/scripts/latlong.html

现在我已经搜索了很多,我找不到使用中心和半径计算多边形的任何好的实现……所以我回到了数学书并尝试自己实现它。 最后我想出了这个…这是100%的好:

  List coordinates = new List(); #region create Polygon Coordinates if (!string.IsNullOrWhiteSpace(bus.Latitude) && !string.IsNullOrWhiteSpace(bus.Longitude) && !string.IsNullOrWhiteSpace(bus.ListingRadius)) { double lat = DegreeToRadian(Double.Parse(bus.Latitude)); double lon = DegreeToRadian(Double.Parse(bus.Longitude)); double dist = Double.Parse(bus.ListingRadius); double angle = 36; for (double i = 0; i <= 360; i += angle) { var bearing = DegreeToRadian(i); var lat2 = Math.Asin(Math.Sin(lat) * Math.Cos(dist / earthRadius) + Math.Cos(lat) * Math.Sin(dist / earthRadius) * Math.Cos(bearing)); var lon2 = lon + Math.Atan2(Math.Sin(bearing) * Math.Sin(dist / earthRadius) * Math.Cos(lat),Math.Cos(dist / earthRadius) - Math.Sin(lat) * Math.Sin(lat2)); coordinates.Add(new double[] { RadianToDegree(lat2), RadianToDegree(lon2) }); } poly.Coordinates = new[] { coordinates.ToArray() }; } #endregion 

如果你测试它,你会发现所有的点都在你给出的确切距离(半径)。 另外不要忘记声明earthRadius。

 private const double earthRadius = 6371.01; 

这会计算十边形的坐标。 你看到使用的角度是36度。 您可以将360度分割为任意数量的边,并将结果放在角度变量中。 无论如何..我希望这可以帮助你@rmx!

为常规多边形生成一组坐标的一种可能实现是:

定义多边形中心半径第一个顶点 1
以角度:360 / n旋转顶点n次2

在这个实现中,我使用向量来存储生成的坐标和递归函数来生成它们:

 void generateRegularPolygon(vector& v, Point& center, int sidesNumber, int radius){ // converted to radians double angRads = 2 * PI / double(sidesNumber); // first vertex Point initial(center.x, center.y - radius); rotateCoordinate(v, center, initial, angRads, sidesNumber); } 

哪里:

 void rotateCoordinate(vector& v, Point& axisOfRotation, Point& initial, double angRads, int numberOfRotations){ // base case: number of transformations < 0 if(numberOfRotations <= 0) return; else{ // apply rotation to: initial, around pivot point: axisOfRotation double x = cos(angRads) * (initial.x - axisOfRotation.x) - sin(angRads) * (initial.y - axisOfRotation.y) + axisOfRotation.x; double y = sin(angRads) * (initial.x - axisOfRotation.x) + cos(angRads) * (initial.y - axisOfRotation.y) + axisOfRotation.y; // store the result v.push_back(Point(x, y)); rotateCoordinate(v, axisOfRotation, Point(x,y), angRads, --numberOfRotations); } } 

注意:

Point是一个将坐标包装成单个数据结构的简单类:

 class Point{ public: Point(): x(0), y(0){ } Point(int xx, int yy): x(xx), y(yy) { } private: int x; int y; }; 

1(就相对于)中心,半径而言。 在我的例子中,第一个顶点从中心向上平移半径长度。

2 n正多边形有n个顶点。

简单的方法是:让我们取N-gone(边数)和边L的长度。角度将是T = 360 / N. 假设一个顶点位于原点上。

 * First vertex = (0,0) * Second vertex = (LcosT,LsinT) * Third vertex = (LcosT+Lcos2T, LsinT+Lsin2T) * Fourth vertex = (LcosT+Lcos2T+Lcos3T, LsinT+Lsin2T+Lsin3T) 

你可以进行循环