Java: создать область отсечения с отверстием?

#java #clipping

#java #отсечение

Вопрос:

Как вы определяете область отсечения (через Graphics2D.clip(Shape) ), в которой есть отверстие?

например: прямоугольник r1 минус другой прямоугольник r2 внутри r1

Я уверен, что на этот вопрос есть простой ответ, но я рисую пробел.

Ответ №1:

Path2D.append() Правило намотки EVEN_ODD, похоже, делает свое дело:

введите описание изображения здесь

 package com.example.test.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class HoleClipper extends JPanel
{
    @Override protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        Rectangle2D r1 = getBounds();
        int margin = 50;
        Rectangle2D r2 = new Rectangle2D.Double(
                r1.getMinX() margin,
                r1.getMinY() margin,
                r1.getWidth()-2*margin,
                r1.getHeight()-2*margin);

        g2d.setColor(Color.YELLOW);
        g2d.fill(r1);

        Path2D p = new Path2D.Double(Path2D.WIND_EVEN_ODD);
        p.append(r1, false);
        p.append(r2, false);
        g2d.clip(p);

        int spacing = 10;
        g2d.setColor(Color.BLACK);
        for (double d = 0; d < r1.getWidth()   r1.getHeight(); d  = spacing)
        {
            Line2D line = new Line2D.Double(0, d, d, 0);
            g2d.draw(line);
        }
    }

    public static void main(String[] args) {
        HoleClipper clipper = new HoleClipper();
        clipper.setPreferredSize(new Dimension(300, 200));

        JFrame frame = new JFrame("HoleClipper");
        frame.setContentPane(clipper);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
  

Ответ №2:

Похоже, это не поддерживается setClip от Graphics. Насколько я читал документацию, поддерживается только прямоугольник:

общедоступный абстрактный набор пустых клипов (Shape clip)

Задает текущей области отсечения произвольную форму клипа. Не все объекты, реализующие интерфейс Shape, могут быть использованы для установки клипа. Единственными объектами Shape, которые гарантированно поддерживаются, являются объекты Shape, которые получены с помощью метода getClip и с помощью объектов Rectangle.Этот метод устанавливает пользовательский клип, который не зависит от отсечения, связанного с границами устройства и видимостью окна.

Ответ №3:

GeneralPath Класс является реализацией Shape , которая может представлять фигуры с отверстиями в них. Вы определяете несколько сегментов пути, один из которых представляет «внешний», а другой — «отверстие». Определите область отсечения, которую вы хотите использовать GeneralPath , а затем вызовите clip() .