Java2D: обрезка графического объекта линией - PullRequest
0 голосов
/ 07 октября 2008

Есть ли способ использовать метод setClip () объекта Graphics для обрезки с использованием формы Line-ish? Сейчас я пытаюсь использовать форму многоугольника, но у меня возникают проблемы с имитацией "ширины" линии. Я в основном рисую линию, и когда я достигаю конца, я перерисовываю ее, но на этот раз вычитаю ширину линии из координаты y:

Polygon poly = new Polygon();

for(int i = 0; i < points.length; i++)
  poly.addPoint(points.[i].x, points.[i].y);

// Retrace line to add 'width'
for(int i = points.length - 1; i >=0; i--)
  poly.addPoint(points[i].x, points[i].y - lineHeight);

Это почти работает, но ширина линии зависит от ее наклона.

Я не могу использовать мазок и DrawLine () методы, поскольку линия может изменить цвет, когда он проходит некоторую произвольную контрольную линию. Есть ли какая-то реализация Shape, которую я пропустил, или простая, которую я могу создать, которая позволит мне сделать это более легко?

Ответы [ 3 ]

1 голос
/ 07 октября 2008

ОК, мне удалось найти довольно хорошее решение без использования метода setClip (). Он включает рисование моего фона в промежуточном объекте Graphics2D, используя setComposite (), чтобы указать, как я хочу замаскировать пиксели, ТО затем рисуя мою линию, используя drawLine () сверху. Получив эту линию, я рисую ее поверх моего исходного объекта Graphics с помощью drawImage. Вот пример:

BufferedImage mask = g2d.getDeviceConfiguration().createCompatibleImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D maskGraphics = (Graphics2D) mask.getGraphics();
maskGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

maskGraphics.setStroke(new BasicStroke(lineWidth));
maskGraphics.setPaint(Color.BLACK);

// Draw line onto mask surface first.
Point prev = line.get(0);
for(int i = 1; i < line.size(); i++)
{
    Point current = line.get(i);
    maskGraphics.drawLine(prev.x, prev.y, current.x, current.y);
        prev = current;
}

// AlphaComposite.SrcIn:    "If pixels in the source and the destination overlap, only the source pixels
//                          in the overlapping area are rendered."
maskGraphics.setComposite(AlphaComposite.SrcIn);

maskGraphics.setPaint(top);
maskGraphics.fillRect(0, 0, width, referenceY);

maskGraphics.setPaint(bottom);
maskGraphics.fillRect(0, referenceY, width, height);

g2d.drawImage(mask, null, 0, 0);
maskGraphics.dispose();
1 голос
/ 07 октября 2008

Если есть лучший способ, я никогда не сталкивался с ним. Лучшее, что я могу придумать, это использовать некоторую тригонометрию, чтобы сделать ширину линии более согласованной.

0 голосов
/ 14 февраля 2011

Может быть, вы могли бы использовать Stroke.createClippedShape для этого? (Может потребоваться использовать Область, чтобы сложить вычеркнутую обводку из / в исходную форму в зависимости от того, что именно вы пытаетесь сделать.

...