绘制具有给定厚度,位置和半径的环.(的Java2D)

ost*_*vil 1 java swing ellipse java-2d graphics2d

我需要绘制一个具有给定厚度的环,看起来像这样:

在此输入图像描述

中心必须是透明的,这样它就不会覆盖以前绘制的形状.(或其他戒指)我尝试过这样的事情:

//g is a Graphics2D object
g.setColor(Color.RED);
g.drawOval(x,y,width,height);
g.setColor(Color.WHITE);
g.drawOval(x+thickness,y+thickness,width-2*thickness,height-2*thickness);
Run Code Online (Sandbox Code Playgroud)

它绘制了一个令人满意的戒指,但它涵盖了其他形状; 内部是白色的,不透明.如何修改/重写我的代码,以便它不会这样做?

Mar*_*o13 8

您可以创建一个AreaEllipse2D描述外圆,并subtract描述内圈椭圆.这样,您将获得Shape可以绘制填充的实际(这将仅指环实际覆盖的区域!).

优点是你确实可以使用戒指的几何形状.例如,这允许您检查环是否形成contains某个点,或者用Paint多于一种颜色填充它:

RingPaint01

这是一个例子,相关部分是createRingShape方法:

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RingPaintTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        RingPaintTestPanel p = new RingPaintTestPanel();
        f.getContentPane().add(p);
        f.setSize(800,800);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}


class RingPaintTestPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;

        g.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

        g.setColor(Color.RED);
        g.drawString("Text", 100, 100);
        g.drawString("Text", 300, 100);

        Shape ring = createRingShape(100, 100, 80, 20); 
        g.setColor(Color.CYAN);
        g.fill(ring);
        g.setColor(Color.BLACK);
        g.draw(ring);

        Shape otherRing = createRingShape(300, 100, 80, 20); 
        g.setPaint(new GradientPaint(
            new Point(250, 40), Color.RED, 
            new Point(350, 200), Color.GREEN));
        g.fill(otherRing);
        g.setColor(Color.BLACK);
        g.draw(otherRing);

    }

    private static Shape createRingShape(
        double centerX, double centerY, double outerRadius, double thickness)
    {
        Ellipse2D outer = new Ellipse2D.Double(
            centerX - outerRadius, 
            centerY - outerRadius,
            outerRadius + outerRadius, 
            outerRadius + outerRadius);
        Ellipse2D inner = new Ellipse2D.Double(
            centerX - outerRadius + thickness, 
            centerY - outerRadius + thickness,
            outerRadius + outerRadius - thickness - thickness, 
            outerRadius + outerRadius - thickness - thickness);
        Area area = new Area(outer);
        area.subtract(new Area(inner));
        return area;
    }

}
Run Code Online (Sandbox Code Playgroud)


cam*_*ckr 6

您可以使用ShapeArea类来创建有趣的效果:

import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
import java.net.*;

public class Subtract extends JPanel
{
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        int size = 100;
        int thickness = 10;
        int innerSize = size - (2 * thickness);

        Shape outer = new Ellipse2D.Double(0, 0, size, size);
        Shape inner = new Ellipse2D.Double(thickness, thickness, innerSize, innerSize);

        Area circle = new Area( outer );
        circle.subtract( new Area(inner) );

        int x = (getSize().width - size) / 2;
        int y = (getSize().height - size) / 2;
        g2d.translate(x, y);

        g2d.setColor(Color.CYAN);
        g2d.fill(circle);
        g2d.setColor(Color.BLACK);
        g2d.draw(circle);

        g2d.dispose();
     }


    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("Subtract");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new Subtract());
        frame.setLocationByPlatform( true );
        frame.setSize(200, 200);
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}
Run Code Online (Sandbox Code Playgroud)

使用区域,您还可以将多个形状一起添加或获取多个形状的交集.