2010-02-17 4 views
1

Я работаю с картами Дандаса и должен наложить карту с пузырьками, изображающими некоторые данные. Я хочу добавить фигуры к карте, чтобы достичь этого. Я могу добавить треугольник (или любой прямолинейное-полигон), как это:Рассчитать точки для создания кривой или сплайна для рисования эллипса

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"); 
} 

Bermuda Triangle

Вы можете видеть, что Бермудский треугольник накладывается на карту в красном цвете. Теперь я хочу вычислить набор точек, чтобы перейти к моему методу AddShape, который бы нарисовал elipse или круг. Мне просто нужен простой алгоритм для вычисления координат 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 - простая тригонометрия, но я страдаю замораживанием мозга. Помогите!

EDIT (! Решаемые с помощью TUR код Нг):

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); 
} 

alt text

Синий круг (через Гринвич) искажается из-картографической проекции над сеткой Робинсона.

ответ

2
double x = centre.x + radius*Math.cos(2*Math.PI/360 * i); 
    double y = centre.y + radius*Math.sin(2*Math.PI/360 * i); 

для круга.

+0

Спасибо, это место! Просто тестирование сейчас ... – grenade

2

скопирован из старой программы C++, я написал давно, он по-прежнему работает на десятках мест:

// Approximate arc with small line segments 
    double sa = dp[ix].center.angle(dp[ix].co); 
    double ea = dp[ix].center.angle(dp[ix+1].co); 
    double r = scale * dp[ix].radius; 
    double rot = ea - sa; 
    double inc = rot; 
    if (dp[ix].dir == ROTCW) rot = -rot; 
    if (rot < 0) rot += 2*PI; 
    // Compute rotation increment that generates less than 1/4 pixel error 
    if (r > 2) inc = 2*acos(1-0.25/r); 
    if (inc >= rot || r < 2) addPoint(x, y); 
    else { 
    int cnt = int(1 + rot/inc); 
    inc = rot/cnt; 
    if (dp[ix].dir == ROTCW) inc = -inc; 
    for (int jx = 0; jx < cnt; ++jx) { 
     x = offsx + scale * dp[ix].center.x + r * cos(sa); 
     y = offsy + scale * dp[ix].center.y + r * sin(sa); 
     addPoint(x, y); 
     sa += inc; 
    } 
    } 

ACOS() такая же, как Math.Acos().

+0

Спасибо, приращение вращения полезно для меня! – grenade

+0

Ханс, Если ты еще вокруг, пожалуйста, не могли бы вы объяснить несколько вещей в этом коде? Какой тип находится в массиве dp? Я бы предположил массив геометрий? Что это за атрибут «co»? И какой вес? Думаю, это вдвойне, но какой величины. У меня есть компилируемая версия, перенесенная на C#, но я все еще далеко от рабочего кода. – corlettk

2

Напомним, что формула для окружности может быть выражена как

(x/r)**2 + (y/r)**2 = 1 

где х и у являются координатами и г является радиусом.

Формула для эллипса может быть выражена как

(x/a)**2 + (y/b)**2 = 1 

где а и Ь являются большими и малыми осями (в произвольном порядке). Выберите a и b, чтобы дать вам эллипс, который «выглядит хорошо».

Как правило, вы выбираете свои точки вокруг круга на равных угловых шагах, чтобы сделать более привлекательным многоугольное приближение к истинному кругу. Для этого нужно использовать подстановки

x = r cos theta 
y = r sin theta 

и запустить цикл для тета от нуля до 2 * пи. Для вашего эллипса, вы будете использовать

x = a cos theta 
y = b sin theta 

Это дает эллипс с большой и малой осей, параллельных осям X и Y и с центром в начале координат. Если вы хотите произвольную ориентацию, с произвольной позицией, вам нужно применить поворот на угол phi и перевод. Любой хороший текст компьютерной графики даст вам необходимые уравнения, скорее всего, в матричной форме.

+0

Спасибо! Теперь я работаю над реализацией elipse, используя ваши предложения. – grenade

Смежные вопросы