2015-04-25 2 views
1

Я хочу получить все вершины из ARC. У меня есть все данные (например: начальная точка, конечная точка, начальный угол, конечный угол, радиус), который будет использоваться для рисования дуги, но мне нужно, чтобы я создал все вершины из данных дуги.Извлечь вершины из ARC в общем виде

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

Я использовал алгоритм Брешенема, но я потерпел неудачу.

Прямо сейчас я использую ниже код, но он не работает ..

  double theta = 2 * 3.1415926/100; 
      double c = Math.cos(theta); 
      double s = Math.sin(theta); 
      double t; 

      double x = ((ArcTo) element).getRadius();//we start at angle = 0 
      double y = 0; 

      for(int ii = 0; ii < 100; ii++) { 
       coordinates.add(new Coordinate(x + element.getCenterPoint().getX(), y + element.getCenterPoint().getY()));//output vertex 

       //apply the rotation matrix 
       t = x; 
       x = c * x - s * y; 
       y = s * t + c * y; 
      } 

Пожалуйста, помогите мне. Спасибо.

+0

Самый простой способ - использовать алгоритм Брешенема. –

+0

@EgorSkriptunoff Thanx за ваш ответ. Я уже пробовал с этим, но не работал для дуги. –

+0

Опубликуйте свой код с реализацией алгоритма Брешенема. Скажите, что именно не работает. –

ответ

0
  1. Первые несколько уточнений

    Я полагаю, что вершин вы имеете в виду пикселей и ARC является стандартным 2D дуга окружности (не эллиптическая дуга !!!) и ваш входными данными являются:

    int (x0,y0),(x1,y1) // star/end points on curve !!! 
    float a0,a1   // start end angles [rad] 
    int (xc,yc)   // center of circle 
    int r    // radius 
    
  2. Не используйте Bresenham

    , потому что вам нужно будет начинать с нуля и вычислять все пиксели до тех пор, пока не начнется точка начала. Затем переверните флаг флага, чтобы вы начали заполнять пиксель с этой точки и останавливались при попадании в конечную точку. Также вам нужно будет обрабатывать обмотку в соответствии с направлением ARC.

  3. Вы можете использовать круг параметрического уравнение

    // just some arc data to test with 
    float r=25.0; 
    float a0= 45.0*M_PI/180.0; 
    float a1=270.0*M_PI/180.0; 
    int xc=100,x0=xc+floor(r*cos(a0)),x1=xc+floor(r*cos(a1)); 
    int yc=100,y0=yc+floor(r*sin(a0)),y1=yc+floor(r*sin(a1)); 
    // arc rasterize code 
    int x,y; 
    float a,da; 
    // here draw pixels x0,y0 and x1,y1 to avoid rounding holes ... 
    if (r) da=0.75/float(r); else da=0.1; // step slightly less then pixel to avoid holes 
    for (a=a0;;a+=da) 
    { 
    x=xc+int(floor(r*cos(a))); 
    y=yc+int(floor(r*sin(a))); 
    // here draw pixel x,y 
    if ((x==x1)&&(y==y1)) // stop if endpoint reach 
        if (fabs(a-a1)<da) // but ignore stop if not at end angle (full or empty circle arc) 
        break; 
    } 
    

    может быть round вместо floor будет иметь меньшую ошибку позиции пикселя. Если ваша конечная точка не соответствует, это будет бесконечно. Если вы подправить чуток конечные условия, которые вы можете избежать даже этого или пересчитывать x1,y1 из a1, как у меня есть ...

  4. Вы можете использовать уравнение (x-xc)^2+(y-yc)^2=r^2

    вам нужно разделить ARC квадрантов и обрабатывать каждый как отдельный цикл дуги через x или y и вычислять другую координату. Цикл по координате, что меняется более

    dx,dy quadrants

    так и в синей областях петли y и в красной петле x.Например красный код города может выглядеть следующим образом:

    int x,y; 
    for (x=_x0;;x++) 
    { 
    y=sqrt((r*r)-((x-xc)*(x-xc))); 
    // here draw pixel x,y 
    if (x==_x1) // stop if endpoint reach 
        break; 
    } 
    

    вам нужно вычислить (_x0,_y0),(_x1,_y1) начало конечных точек разреза части АРК внутри квадранта и сделать _x0<=_x1.


    Значение _x петельного старт/конечную точку координат будет xc +/- sqrt(r) или x0 или x1
    значения для _y петельных старта/конечной точки координат будет yc +/- sqrt(r) или y0 или y1

    Синие части сделаны аналогичным образом (просто замените/замените x и y). Этот подход немного сложнее из-за резки, но может выполняться исключительно на целых числах. sqrt может быть увеличен на LUT (ограничение максимального радиуса) и ^2 также может быть дополнительно оптимизирован.

[Примечания]

так, если я резюмировать параметрическое уравнение является простейшим для реализации, но самый медленный. Тогда есть подход sqrt, который может быть выполнен так же быстро, как и Bresenham (и может быть еще быстрее с LUT), но нужен код для резки ARC для квадрантов, которым нужно немного if s до рендеринга.

Всех код в C++ и могут быть дополнительно улучшены, как избежать некоторых int/float преобразования, предварительно вычислить некоторые значения перед циклом, и т.д. ...

Последнее идет Bresenham, но вам нужно изменить несколько вещи внутри, и когда вы не знаете, что делаете, вы легко можете потеряться. Это также необходимо сократить до октанта, поэтому сложность изменений намного больше, чем sqrt подход