How to paint a group of QuadCurves using Java Graphics2D

后端 未结 1 1280
失恋的感觉
失恋的感觉 2020-12-22 13:56

I have a lot of QuadCurve2D methods in a drawing, but when I fill them they don\'t actually fill the whole image.

Code for fill and curves:

g2.setStr         


        
相关标签:
1条回答
  • 2020-12-22 14:53

    "A" solution might be to paint the "shape" to a BufferedImage and simply scale the image, but this will scale the stroke/line size as well.

    A better solution might be to encapsulate the drawing into a Shape and use Shape#createTransformedShape instead.

    public class Cat extends Path2D.Double {
    
        public Cat() {
            //Left Ear
            moveTo(145, 155);
            curveTo(145, 155, 137.5, 49, 150, 49);
            moveTo(150, 49);
            curveTo(150, 49, 156.25, 49, 200, 100);
            // Between Ears
            moveTo(200, 100);
            curveTo(200, 100, 237.5, 88, 262.5, 87.5);
            // Right ear
            moveTo(262.5, 87.5);
            curveTo(262.5, 87.5, 287.5, 25, 300, 25);
            moveTo(300, 25);
            curveTo(300, 25, 312.5, 25, 337.5, 137.5);
            // Head phone left
            moveTo(300, 25);
            append(new CubicCurve2D.Double(145, 155, 75, 175, 100, 250, 150, 250), false);
            moveTo(337.5, 137.5);
            append(new CubicCurve2D.Double(337.5, 137.5, 387.5, 137.5, 393.75, 188, 362.5, 225), false);
            moveTo(109, 177);
            curveTo(109, 177, 150, 75, 225, 50);
            moveTo(225, 50);
            curveTo(225, 50, 300, 50, 372, 150);
            moveTo(135, 155);
            curveTo(135, 155, 150, 112.5, 212.5, 78);
            moveTo(212.5, 78);
            curveTo(212.5, 78, 306.25, 78, 351, 137.5);
            moveTo(150, 250);
            curveTo(150, 250, 162.5, 275, 200, 300);
            moveTo(362.5, 225);
            curveTo(362.5, 225, 363.5, 237.5, 350, 262.5);
            moveTo(200, 300);
            append(new CubicCurve2D.Double(200, 300, 87.5, 300, 87.5, 375, 188.5, 362.5), false);
            moveTo(350, 262.5);
            append(new CubicCurve2D.Double(350, 262.5, 425, 237.5, 450, 300, 375, 325), false);
            moveTo(188.5, 362.5);
            curveTo(188.5, 362.5, 154, 425, 200, 512.5);
            moveTo(375, 325);
            curveTo(375, 325, 388.5, 356.25, 387.5, 412.5);
            moveTo(200, 512.5);
            curveTo(200, 512.5, 125, 500, 130, 562.5);
            moveTo(130, 562.5);
            curveTo(130, 562.5, 175, 575, 262.5, 562.5);
            moveTo(262.5, 562.5);
            curveTo(262.5, 562.5, 237.5, 400, 268.75, 363);
            moveTo(268.75, 363);
            curveTo(268.75, 363, 318.75, 362.5, 337.5, 475);
            moveTo(337.5, 475);
            curveTo(337.5, 475, 400, 480, 455, 470);
            moveTo(455, 470);
            curveTo(455, 470, 450, 400, 387.5, 412.5);
    
            moveTo(268.75, 363);
            append(new CubicCurve2D.Double(268.75, 363, 287.5, 450, 125, 387.5, 62.5, 400), false);
    
            moveTo(62.5, 400);
            curveTo(62.5, 400, 25, 425, 200, 437.5);
            moveTo(200, 437.5);
            curveTo(200, 437.5, 287.5, 425, 300, 375);
    
            int[] x = {175, 200, 225, 225, 287, 300, 309, 337, 325, 309, 302, 292, 240, 227, 226, 215};
            int[] y = {225, 210, 237, 200, 187, 212, 187, 187, 262, 262, 230, 268, 275, 250, 277, 281};
            GeneralPath mouthAndTeeth = new GeneralPath();
    
            mouthAndTeeth.moveTo(x[0], y[0]);
    
            for (int index = 1; index < x.length; index++) {
                mouthAndTeeth.lineTo(x[index], y[index]);
            }
    
            mouthAndTeeth.closePath();
            append(mouthAndTeeth, false);
        }
    
    }
    

    And then scale the shape based on the available space of the container...

    Fat Cat

    import java.awt.BasicStroke;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Shape;
    import java.awt.geom.AffineTransform;
    import java.awt.geom.CubicCurve2D;
    import java.awt.geom.GeneralPath;
    import java.awt.geom.Path2D;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private Cat cat;
    
            public TestPane() {
                cat = new Cat();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setStroke(new BasicStroke(5));
    
                int catWidth = cat.getBounds().x + cat.getBounds().width;
                int catHeight = cat.getBounds().y + cat.getBounds().height;
    
                int width = getWidth() - 1;
                int height = getHeight() - 1;
    
                double scaleWidth = width / (double)catWidth;
                double scaleHeight = height / (double)catHeight;
    
                double scale = Math.min(scaleHeight, scaleWidth);
                AffineTransform at = AffineTransform.getScaleInstance(scale, scale);
                Shape shape = cat.createTransformedShape(at);
    
                g2d.draw(shape);
    
                g2d.dispose();
            }
    
        }
    
    }
    

    Which you use will come down to needs, for example, using a Shape like this, won't allow you to color individual sections differently

    0 讨论(0)
提交回复
热议问题