2009-03-09 11 views
3

У меня есть Rectangle2D и Line2D. Я хочу «закрепить» линию так, чтобы осталась только часть линии, которая находится внутри прямоугольника. Если ни одна из строк не находится внутри прямоугольника, я хочу, чтобы линия была установлена ​​на (0,0,0,0). В основном что-то вроде линийСамый элегантный способ закрепить линию?

Rectangle2D.intersect(Line2D src, Line2D dest) 

или что-то подобное.

Есть ли способ сделать это с помощью API java.awt.geom? Или элегантный способ закодировать его «вручную»?

ответ

0

Ну, я закончил это сам.

Для тех, кто вас интересует, я решил решить эту проблему, повернув линию в прямоугольник (с помощью getBounds), затем используя Rectangle.intersect(clipRect,lineRect,intersectLineRect), чтобы создать пересечение, а затем переверните перекресток обратно в линию.

+0

не работает, если линия имеет отрицательный наклон – necromancer

+0

В этой части можно использовать немного более подробную информацию: «поворот пересечения обратно в линию». Конечные точки обрезанной линии могут лежать на краях прямоугольника пересечения. –

0

Обычным делом является ограничение области отсечения в графическом контексте с помощью Graphics2D.clip. Возможно, вы захотите позвонить Graphics.create, чтобы вы не вмешивались в исходный контекст.

Graphics2D g = (Graphics2D)gOrig.create(); 
try { 
    g.clip(clip); 
    ... 
} finally { 
    g.dispose(); 
} 
+0

Извините, но я фактически не работаю с графическим контекстом. – Epaga

+0

Это то, для чего предназначен java.awt.geom. –

+0

В противном случае, у вас есть необработанные данные, чтобы выполнить математику самостоятельно. –

3

Исходный код Rectangle2D.intersectLine() может быть полезным:

public boolean intersectsLine(double x1, double y1, double x2, double y2) { 
    int out1, out2; 
    if ((out2 = outcode(x2, y2)) == 0) { 
     return true; 
    } 
    while ((out1 = outcode(x1, y1)) != 0) { 
     if ((out1 & out2) != 0) { 
      return false; 
     } 
     if ((out1 & (OUT_LEFT | OUT_RIGHT)) != 0) { 
      double x = getX(); 
      if ((out1 & OUT_RIGHT) != 0) { 
       x += getWidth(); 
      } 
      y1 = y1 + (x - x1) * (y2 - y1)/(x2 - x1); 
      x1 = x; 
     } else { 
      double y = getY(); 
      if ((out1 & OUT_BOTTOM) != 0) { 
       y += getHeight(); 
      } 
      x1 = x1 + (y - y1) * (x2 - x1)/(y2 - y1); 
      y1 = y; 
     } 
    } 
    return true; 
} 

где outcode() определяется как:

public int outcode(double x, double y) { 
    int out = 0; 
    if (this.width <= 0) { 
     out |= OUT_LEFT | OUT_RIGHT; 
    } else if (x < this.x) { 
     out |= OUT_LEFT; 
    } else if (x > this.x + this.width) { 
     out |= OUT_RIGHT; 
    } 
    if (this.height <= 0) { 
     out |= OUT_TOP | OUT_BOTTOM; 
    } else if (y < this.y) { 
     out |= OUT_TOP; 
    } else if (y > this.y + this.height) { 
     out |= OUT_BOTTOM; 
    } 
    return out; 
} 

(от OpenJDK)

Оно не должно быть очень трудно изменить это для клипа вместо возврата true или false.

+0

Хотя части этого булевого теста аналогичны алгоритму Коэна-Сазерленда, мне было легче начать с псевдокода для алгоритма, чем адаптировать логический тест AWT 'intersectsLine()'. Но я думаю, что вспомогательная функция 'outcode()' может быть в значительной степени использована как есть. –

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

  • Нет связанных вопросов^_^