计算点以创建曲线或样条线以绘制椭圆
我正在使用 Dundas 地图,需要用描绘一些数据的气泡覆盖地图。我想向地图添加形状以实现此目的。我可以添加一个三角形(或任何直线多边形),如下所示:
public static void AddShape(this MapControl map, List<MapPoint> points, Color color, string name)
{
if (points[0].X != points[points.Count - 1].X && points[0].Y != points[points.Count - 1].Y)
points.Add(points[0]);
var shape = new Shape
{
Name = name,
BorderColor = color,
BorderStyle = MapDashStyle.Solid,
BorderWidth = 1,
Color = Color.FromArgb((int)(255 * (0.3)), color)
};
var segments = new[] {new ShapeSegment {Type = SegmentType.Polygon, Length = points.Count}};
shape.AddSegments(points.ToArray(), segments);
map.Shapes.Add(shape);
}
public static void AddBermudaTriangle(this MapControl map)
{
var points = new List<MapPoint>
{
new MapPoint(-80.15, 26.0667),
new MapPoint(-64.75, 32.333),
new MapPoint(-66.07, 18.41)
};
map.AddShape(points, Color.Red, "Bermuda Triangle");
}
您可以看到百慕大三角以红色覆盖在地图上。现在我想计算一组点传递给我的 AddShape 方法,该方法将绘制椭圆或圆形。我只需要一个简单的算法来计算给定数量的点的 x 和 y 坐标。也许从代表圆心的给定点开始。例如:
public static void AddCircle(this MapControl map, Point centre, double radius, string name)
{
var points = new List<MapPoint>();
const int n = 360;
for(var i = 0; i < n; i++)
{
//calculate x & y using n, radius and centre
double x = 0;
double y = 0;
points.Add(new MapPoint(x, y));
}
map.AddShape(points, Color.Red, name);
}
我知道 x,y 计算是简单的三角函数,但我的大脑冻结了。帮助!
编辑(使用 tur!ng 的代码解决):
public static void AddCircle(this MapControl map, Color color, MapPoint centre, double radius, string name)
{
var points = new List<MapPoint>();
const int n = 360;
for(var i = 0; i < n; i++)
{
var x = (radius * Math.Cos(i * Math.PI / 180)) + centre.X;
var y = (radius * Math.Sin(i * Math.PI / 180)) + centre.Y;
points.Add(new MapPoint(x, y));
}
map.AddShape(points, color, name);
}
蓝色圆圈 (由于罗宾逊网格上的地图投影,格林威治上空的地图会变形。
I am working with Dundas maps and need to overlay the map with bubbles depicting some data. I want to add shapes to the map in order to achieve this. I can add a triangle (or any straight-line-polygon) like this:
public static void AddShape(this MapControl map, List<MapPoint> points, Color color, string name)
{
if (points[0].X != points[points.Count - 1].X && points[0].Y != points[points.Count - 1].Y)
points.Add(points[0]);
var shape = new Shape
{
Name = name,
BorderColor = color,
BorderStyle = MapDashStyle.Solid,
BorderWidth = 1,
Color = Color.FromArgb((int)(255 * (0.3)), color)
};
var segments = new[] {new ShapeSegment {Type = SegmentType.Polygon, Length = points.Count}};
shape.AddSegments(points.ToArray(), segments);
map.Shapes.Add(shape);
}
public static void AddBermudaTriangle(this MapControl map)
{
var points = new List<MapPoint>
{
new MapPoint(-80.15, 26.0667),
new MapPoint(-64.75, 32.333),
new MapPoint(-66.07, 18.41)
};
map.AddShape(points, Color.Red, "Bermuda Triangle");
}
You can see that the Bermuda Triangle overlays the map in red. Now I want to calculate a set of points to pass to my AddShape method that would draw an elipse or circle. I just need a simple algorithm for calculating the x and y coordinates of a given number of points. Perhaps starting with a given point that would represent the centre of the circle. For example:
public static void AddCircle(this MapControl map, Point centre, double radius, string name)
{
var points = new List<MapPoint>();
const int n = 360;
for(var i = 0; i < n; i++)
{
//calculate x & y using n, radius and centre
double x = 0;
double y = 0;
points.Add(new MapPoint(x, y));
}
map.AddShape(points, Color.Red, name);
}
I know that the x,y calculation is simple trigonometry but I'm suffering a brain freeze. Help!
EDIT (Solved using tur!ng's code):
public static void AddCircle(this MapControl map, Color color, MapPoint centre, double radius, string name)
{
var points = new List<MapPoint>();
const int n = 360;
for(var i = 0; i < n; i++)
{
var x = (radius * Math.Cos(i * Math.PI / 180)) + centre.X;
var y = (radius * Math.Sin(i * Math.PI / 180)) + centre.Y;
points.Add(new MapPoint(x, y));
}
map.AddShape(points, color, name);
}
The blue circle (over Greenwich) is distorted because of the map projection over a Robinson grid.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一个圆圈。
for a circle.
从我很久以前写的一个旧的 C++ 程序复制而来,它仍然在几十个地方运行:
acos() 与 Math.Acos() 相同。
Copied from an old C++ program I wrote a long time ago, it still runs at dozens of places:
acos() is the same as Math.Acos().
回想一下,圆的公式可以表示为
其中 x 和 y 是坐标,r 是半径。
椭圆的公式可以表示为
其中a和b是长半轴和短半轴(没有特定的顺序)。选择a和b给你一个“看起来不错”的椭圆。
您通常希望以相等的角度步长围绕圆选取点,以便对真实的圆做出更好看的多边形近似。为此,您可以使用替换
并运行从 0 到 2*pi 的 theta 循环。对于椭圆,您将使用
这会给您一个椭圆,其长半轴和短半轴平行于 X 轴和 Y 轴,并以原点为中心。如果您想要任意方向、任意位置,则需要应用角度 phi 的旋转和平移。任何好的计算机图形学文本都会为您提供必要的方程,最有可能以矩阵形式。
Recall that the formula for a circle may be expressed as
where x and y are coordinates and r is radius.
The formula for an ellipse may be expressed as
where a and b are the semimajor and semiminor axes (in no particular order). Choose a and b to give you an ellipse that "looks good".
You usually want to pick your points around a circle at equal angular steps, to make a better looking polygonal approximation to a true circle. For this, you use the substitutions
and run your loop for theta from zero to 2*pi. For your ellipse, you'll use
This gives you an ellipse with the semimajor and semiminor axes parallel to the X and Y axes and centered at the origin. If you want an arbitrary orientation, with an arbitrary position, you'll need to apply a rotation by an angle phi, and a translation. Any good computer graphics text will give you the necessary equations, most likely in matrix form.