2013-12-03 5 views
2

Задача: Добавить n пиксельный буфер в существующий многоугольник (гарантированный быть закрытым, неперекрывающимся и точками по часовой стрелке) при сохранении центроид многоугольника.Добавьте N пиксельный буфер в многоугольник (регион/путь), поддерживая Centroid в C#

Текущий: У меня есть класс PolyRegion, который содержит путь System.Drawing и System.Drawing Region. Когда я создаю экземпляр класса, я добавляю буфер факторов в путь и масштабирую/преобразую его. Результат сдвигается, если масштабируется относительно центра тяжести.

Пример: Зеленый полигон является оригиналом. Когда я масштабирую его в n раз, я получаю/хочу фиолетовый многоугольник (центрированный по центру).

enter image description here

Вопрос: Как можно масштабировать относительно центроида? AM Мне лучше масштабировать каждую точку в массиве точек или масштабировать Path/Region?

Код:

public PolyRegion(Int32 Id, List<Point> Points) 
{ 
    this.Id = Id; 
    this.Points = Points; 
    this.Path = this.CreatePath(); 

    float factor = 10; 
    float wScale = (float)((this.Path.GetBounds().Width - factor)/this.Path.GetBounds().Width); 
    float hScale = (float)((this.Path.GetBounds().Height - factor)/this.Path.GetBounds().Height); 
    Matrix transformMatrix = new Matrix(); 
    transformMatrix.Scale(wScale, hScale); 
    this.Path.Transform(transformMatrix); 

    this.Region = new Region(this.Path); 
    this.Area = CalculateArea(); 
} 

ответ

0

Это больше математической/геометрический вопрос, чем программирование одного:

1) Перевести фигуру из положения центроида (х, у) в (0,0) координата

2) Масштаб по вашему желаемому коэффициенту.

3) Вернитесь к первоначальному центроиду.

+0

Поскольку вы не укажете его в своем коде, я бы вычислил (x, y) как среднее из всех точки с вашей фигуры. – SJuan76

+0

Почему № 1 необходимо? Почему бы просто не масштабировать, а затем переставлять? Кажется, есть лучший способ сделать это. –

+0

Обычно графические алгоритмы имеют дело с матрицами, поскольку он предлагает однородный инструмент для всех преобразований, а в настоящее время HW оптимизирован. Конечно, способ, который вы предлагаете, возможен для этой конкретной ситуации; если центроид равен '(x, y)', то после приближения к шкале 'k' он будет' (kx, ky) '. Исчисление необходимого перевода оставлено в качестве упражнения для читателя :-). – SJuan76

0

Я решил повернуть матрицу и область шкалы и преобразовать и перейти с более чистым подходом.

Сначала я рассчитать центроид моего polgon:

private Point GetCentroid() 
{ 
int centroidX = 0; 
int centroidY = 0; 
int pointCount = this.Points.Count(); 

for (int i = 0; i < pointCount; i++) 
{ 
centroidX = centroidX + this.Points[i].X; 
centroidY = centroidY + this.Points[i].Y; 
} 

centroidX = centroidX/pointCount; 
centroidY = centroidY/pointCount; 

return new Point(centroidX, centroidY); 
} 

Затем цикл через каждую точку и буфер его S и T (мой фактор буфер):

private List<Point> GetBufferedPoints() 
{ 
int c = this.Centroid.X; 
int d = this.Centroid.Y; 
int s = this.BufferFactor; 
int t = this.BufferFactor; 
int pointCount = this.Points.Count(); 
PointsBuffered = new List<Point>(); 

for (int i = 0; i < pointCount; i++) 
{ 
int x = this.Points[i].X; 
int y = this.Points[i].Y; 
PointsBuffered.Add(new Point((s * (x - c)) + c, (t * (y - d)) + d)); 
} 

return PointsBuffered; 
} 

Результат:

enter image description here