如何在Java中互锁形状

时间:2016-02-13 17:02:15

标签: java swing paint

我有一个项目,我必须绘制奥运五环,我很难让它看起来像环互锁。这是一张显示我的意思的图片。

enter image description here

注意他们是如何互锁的?这就是我现在想要的东西,我只有彼此重叠的形状。这就是我现在所拥有的。

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Color; //sets color
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.AlphaComposite;

class ColoredOlypmicRings extends JFrame {

    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        float strokeThickness = 27.0f;
        float arcThickness = 9.0f;
        BasicStroke Outline = new BasicStroke(strokeThickness);
        BasicStroke arcOutline = new BasicStroke(arcThickness);
        g2d.setStroke(Outline);
        g2d.setColor(Color.blue);
        g2d.drawOval(100, 100, 300, 300);
        g2d.setColor(Color.yellow);
        g2d.drawOval(265, 300, 300, 300);
        g2d.setColor(Color.black);
        g2d.drawOval(430, 100, 300, 300);
        g2d.setColor(Color.green);
        g2d.drawOval(595, 300, 300, 300);
        g2d.setColor(Color.red);
        g2d.drawOval(760, 100, 300, 300);
        g2d.setStroke(arcOutline);
        g2d.setColor(Color.white);
        g2d.drawArc(253, 378, 50, 75, -230, 58); // -270 start
        g2d.drawArc(290, 370, 50, 75, -230, 58);
        g2d.drawArc(360, 285, 50, 75, -230, 58);
        g2d.drawArc(405, 285, 50, 75, -230, 58);

    }

    public ColoredOlypmicRings() {
        setSize(1200, 800);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        ColoredOlypmicRings guiWindow = new ColoredOlypmicRings();
        guiWindow.setVisible(true);
    }

}

2 个答案:

答案 0 :(得分:5)

  1. 绘制颜色的弧线,组合后形成圆形,而不是绘制整个椭圆形。
  2. 最后需要绘制顶层弧。这可能需要一些试验和错误,但你可以这样做。
  3. 一般建议永远不要在顶级窗口中绘制,例如JFrame。
  4. 而是在JPanel的paintComponent方法中绘制,然后在JFrame中显示该JPanel
  5. 始终在覆盖的方法中调用超级绘画方法。
  6. 使用Graphics2D setRenderingHints平滑绘图并在上打开消除锯齿
  7. 第一次迭代 - 尚未完全修复:

    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.Stroke;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class OlympicRings extends JPanel {
        private static final Color BG = Color.WHITE;
        private static final int OVAL_WIDTH = 300;
        private static final int OVAL_HEIGHT = OVAL_WIDTH;
        private static final int X_START = 100;
        private static final int Y_START = X_START;
        private static final int DELTA_X = 175;
        private static final int DELTA_Y = 180;
        private static final Color COLOR_GOLD = new Color(242, 205, 25);
        private static final Stroke INNER_STROKE = new BasicStroke(30f);
        private static final Stroke OUTER_STROKE = new BasicStroke(40f);
        private static final int ARC_LENGTH = 30;
        private static final int CIRCLE_DEGREES = 360;
    
        public OlympicRings() {
            setBackground(BG);
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
            int x = X_START;
            int y = Y_START;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH);
            x += DELTA_X;
            y += DELTA_Y;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH);        
            x += DELTA_X;
            y -= DELTA_Y;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH);        
            x += DELTA_X;
            y += DELTA_Y;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH);        
            x += DELTA_X;
            y -= DELTA_Y;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.RED, OVAL_WIDTH);
    
            x = X_START;
            y = Y_START;
            int angle = CIRCLE_DEGREES - ARC_LENGTH;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH, angle, ARC_LENGTH);
            x += DELTA_X;
            y += DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH, 0, ARC_LENGTH);
            x += DELTA_X;
            y -= DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH, angle, ARC_LENGTH);        
            x += DELTA_X;
            y += DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH, 0, ARC_LENGTH);        
    
            g2.dispose();        
        }
    
        private void myDrawArc(Graphics2D g2, Stroke innerStroke, Stroke outerStroke, int x, int y,
                Color bg2, Color color, int ovalWidth, int start, int end) {
            g2.setStroke(outerStroke);
            g2.setColor(bg2);
            g2.drawArc(x, y, ovalWidth, ovalWidth, start, end);
    
            g2.setStroke(innerStroke);
            g2.setColor(color);
            g2.drawArc(x, y, ovalWidth, ovalWidth, start, end);        
        }
    
        private void myDrawOval(Graphics2D g2, Stroke innerStroke, Stroke outerStroke, int x, int y,
                Color bg2, Color color, int ovalWidth) {
            g2.setStroke(outerStroke);
            g2.setColor(bg2);
            g2.drawOval(x, y, ovalWidth, ovalWidth);
    
            g2.setStroke(innerStroke);
            g2.setColor(color);
            g2.drawOval(x, y, ovalWidth, ovalWidth);
        }
    
        @Override
        public Dimension getPreferredSize() {
            if (isPreferredSizeSet()) {
                return super.getPreferredSize();
            }
            int w = 2 * X_START + DELTA_X * 4 + OVAL_WIDTH;
            int h = 2 * Y_START + DELTA_Y + OVAL_HEIGHT;
            return new Dimension(w, h);
        }
    
        private static void createAndShowGui() {
            OlympicRings mainPanel = new OlympicRings();
    
            JFrame frame = new JFrame("OlympicRings");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.getContentPane().add(mainPanel);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                createAndShowGui();
            });
        }
    }
    

    当我的背景笔划超出弧的末端时,这并不完全存在:

    enter image description here

    仍在努力。

    稍微好一些:

    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.Stroke;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class OlympicRings extends JPanel {
        private static final Color BG = Color.WHITE;
        private static final int OVAL_WIDTH = 300;
        private static final int OVAL_HEIGHT = OVAL_WIDTH;
        private static final int X_START = 100;
        private static final int Y_START = X_START;
        private static final int DELTA_X = 175;
        private static final int DELTA_Y = 180;
        private static final Color COLOR_GOLD = new Color(242, 205, 25);
        private static final Stroke INNER_STROKE = new BasicStroke(30f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND);
        private static final Stroke OUTER_STROKE = new BasicStroke(40f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
        private static final int ARC_LENGTH = 30;
        private static final int CIRCLE_DEGREES = 360;
    
        public OlympicRings() {
            setBackground(BG);
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
            int x = X_START;
            int y = Y_START;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH);
            x += DELTA_X;
            y += DELTA_Y;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH);        
            x += DELTA_X;
            y -= DELTA_Y;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH);        
            x += DELTA_X;
            y += DELTA_Y;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH);        
            x += DELTA_X;
            y -= DELTA_Y;
            myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.RED, OVAL_WIDTH);
    
            x = X_START;
            y = Y_START;
            int angle = CIRCLE_DEGREES - ARC_LENGTH;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH, angle, ARC_LENGTH);
            x += DELTA_X;
            y += DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH, 0, ARC_LENGTH);
            x += DELTA_X;
            y -= DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH, angle, ARC_LENGTH);        
            x += DELTA_X;
            y += DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH, 0, ARC_LENGTH);        
    
            g2.dispose();        
        }
    
        private void myDrawArc(Graphics2D g2, Stroke innerStroke, Stroke outerStroke, int x, int y,
                Color bg2, Color color, int ovalWidth, int start, int end) {
            g2.setStroke(outerStroke);
            g2.setColor(bg2);
            g2.drawArc(x, y, ovalWidth, ovalWidth, start, end);
    
            g2.setStroke(innerStroke);
            g2.setColor(color);
            g2.drawArc(x, y, ovalWidth, ovalWidth, start, end);        
        }
    
        private void myDrawOval(Graphics2D g2, Stroke innerStroke, Stroke outerStroke, int x, int y,
                Color bg2, Color color, int ovalWidth) {
            g2.setStroke(outerStroke);
            g2.setColor(bg2);
            g2.drawOval(x, y, ovalWidth, ovalWidth);
    
            g2.setStroke(innerStroke);
            g2.setColor(color);
            g2.drawOval(x, y, ovalWidth, ovalWidth);
        }
    
        @Override
        public Dimension getPreferredSize() {
            if (isPreferredSizeSet()) {
                return super.getPreferredSize();
            }
            int w = 2 * X_START + DELTA_X * 4 + OVAL_WIDTH;
            int h = 2 * Y_START + DELTA_Y + OVAL_HEIGHT;
            return new Dimension(w, h);
        }
    
        private static void createAndShowGui() {
            OlympicRings mainPanel = new OlympicRings();
    
            JFrame frame = new JFrame("OlympicRings");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.getContentPane().add(mainPanel);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                createAndShowGui();
            });
        }
    }
    

    enter image description here

    最新变化:

            x = X_START;
            y = Y_START;
            int angle = CIRCLE_DEGREES - ARC_LENGTH;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH, angle, ARC_LENGTH);
            x += DELTA_X;
            y += DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH, 57, ARC_LENGTH);
            x += DELTA_X;
            y -= DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH, angle, ARC_LENGTH);        
            x += DELTA_X;
            y += DELTA_Y;
            myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH, 57, ARC_LENGTH);  
    

    结果:

    enter image description here

答案 1 :(得分:1)

这是OP发布的代码的输出: Output of OP's code

环周围的白色边框 - 只有当环相互交叉时,才应尝试对边框进行硬编码,在绘制任何颜色的圆弧之前应绘制白色圆弧,白色圆弧具有比彩色的笔画更宽。

重叠 - 如果您依次绘制所有戒指,则必须修复至少4个重叠,以使其看起来像您之后的徽标。您应该通过仅重绘相应的弧形部分来重新绘制这4个重叠中的每一个(蓝色黄色,黄色黑色,黑色绿色,绿色红色)。

颜色&距离 - 使用颜色选择器工具查找样本图像中颜色的确切RGB值。你还应该将你的戒指水平放置一点,然后将顶行拉近底行。

编辑:按照我自己的建议,这是我的输出

olympic logo

生成它的程序(省略import语句)

public static void paintRing(Graphics2D g, BasicStroke bs, BasicStroke fs, 
        double x, double y, 
        double r, double rw, Color color, int a0, int a) {
    g.setColor(Color.white);
    g.setStroke(new BasicStroke((float)rw*1.5f));
    g.drawArc((int)x, (int)y, (int)r, (int)r, a0+5, a-10);
    g.setColor(color);
    g.setStroke(new BasicStroke((float)rw));
    g.drawArc((int)x, (int)y, (int)r, (int)r, a0, a);
}

public void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D)g;
    RenderingHints rh = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    rh.put( RenderingHints.KEY_RENDERING, 
            RenderingHints.VALUE_RENDER_QUALITY);
    g2d.setRenderingHints(rh);

    double w = getWidth();

    // eyeballed measurements
    double m = w/12;
    double dx = w/7;
    double dy = w/8;
    double x = m;
    double y = .7 * m;
    double r = w/4;

    // for partial lines
    int fwdStart = -30;
    int topStart = 90-30;

    // background & foreground strokes
    float rw = (float)w/40;
    BasicStroke bs = new BasicStroke(rw*1.5f);
    BasicStroke fs = new BasicStroke(rw);

    // colors
    Color blue = new Color(0, 133, 199);
    Color gold = new Color(244, 195, 0);
    Color black = Color.black;
    Color green = new Color(0, 159, 61);
    Color red = new Color(223, 0, 36);

    paintRing(g2d, fs, bs, x, y, r, rw, blue, 0, 360);
    paintRing(g2d, fs, bs, x+dx, y+dy, r, rw, gold, 0, 360);        
    paintRing(g2d, fs, bs, x+2*dx, y, r, rw, black, 0, 360);

    // mesh blue-gold-black
    paintRing(g2d, fs, bs, x+dx, y+dy, r, rw, gold, topStart, 60);
    paintRing(g2d, fs, bs, x, y, r, rw, blue, fwdStart, 60);

    paintRing(g2d, fs, bs, x+3*dx, y+dy, r, rw, green, 0, 360);
    paintRing(g2d, fs, bs, x+4*dx, y, r, rw, red, 0, 360);

    // mesh red-green-black
    paintRing(g2d, fs, bs, x+3*dx, y+dy, r, rw, green, topStart, 60);
    paintRing(g2d, fs, bs, x+2*dx, y, r, rw, black, fwdStart, 60);
}

public static void main(String[] args) {
    JFrame jf = new JFrame("Test");
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.add(new Olympic());
    jf.setSize(800, 400);
    jf.setLocationByPlatform(true);
    jf.setVisible(true);
}