【问题标题】:Checking if a rectangle intersects text检查矩形是否与文本相交
【发布时间】:2019-03-15 20:21:29
【问题描述】:

我有一个名为“MapObject”的类,它允许您定义它是什么,它做什么。我最近在其中添加了文本,它工作正常,但是碰撞是一个矩形,在某些情况下并不可怕,但是我希望有一个与文本匹配的碰撞框(也就是检查 1x1 矩形是否与文本,但仍然可以在字母之间)

我尝试了以下方法:

GlyphVector vec = ob.font.createGlyphVector(new Canvas().getFontMetrics(ob.font).getFontRenderContext(), ob.text);
Shape textSh = vec.getOutline();
Area obSh = new Area(new Rectangle(x,y,o.width,o.height));
obSh.intersect(new Area(textSh));
boolean inter = !obSh.isEmpty();

但是它不起作用,我想是因为位置,但是我不知道如何在其中添加位置。 谢谢。

【问题讨论】:

    标签: java text awt java-2d


    【解决方案1】:

    您可能需要做的一件事是将GlyphVector 或Rectangle 转换为正确的上下文。

    我的意思是,GlyphVector 仅代表 0x0 原点处的文本,因此如果文本显示在屏幕上的其他位置,那么您没有得到正确的表示。

    幸运的是,有人真正考虑过这个用例并提供了一些功能来实现它。详情请见GlyphVector#getOutline(float, float)。

    然后你可以使用它...

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.Shape;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.font.FontRenderContext;
    import java.awt.font.GlyphVector;
    import java.awt.geom.Rectangle2D;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private List<Rectangle> boxes;
            private Map<Rectangle, Point> vectors;
    
            public TestPane() {
                boxes = new ArrayList<>(25);
                vectors = new HashMap<>(25);
                Random random = new Random();
                for (int index = 0; index < 10; index++) {
                    int x = random.nextInt(400 - 10);
                    int y = random.nextInt(400 - 10);
    
                    Rectangle box = new Rectangle(x, y, 10, 10);
                    boxes.add(box);
    
                    int xDelta = random.nextBoolean() ? 1 : -1;
                    int yDelta = random.nextBoolean() ? 1 : -1;
    
                    vectors.put(box, new Point(xDelta, yDelta));
                }
    
                Timer timer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        for (Rectangle box : boxes) {
                            Point delta = vectors.get(box);
    
                            if (delta == null) {
                                int xDelta = random.nextBoolean() ? 1 : -1;
                                int yDelta = random.nextBoolean() ? 1 : -1;
                                delta = new Point(xDelta, yDelta);
                            }
    
                            int x = box.x + delta.x;
                            int y = box.y + delta.y;
    
                            if (x < 0) {
                                x = 0;
                                delta.x *= -1;
                            } else if (x + box.width > getWidth()) {
                                x = getWidth() - box.width;
                                delta.x *= -1;
                            }
                            if (y < 0) {
                                y = 0;
                                delta.y *= -1;
                            } else if (y + box.height > getHeight()) {
                                y = getHeight() - box.height;
                                delta.y *= -1;
                            }
    
                            box.setLocation(x, y);
                            vectors.put(box, delta);
                        }
                        repaint();
                    }
                });
                timer.start();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(400, 200);
            }
    
            protected Shape getTextShape() {
                Graphics2D g2d = (Graphics2D) getGraphics();
                if (g2d == null) {
                    return null;
                }
                Font font = new Font("Arial", Font.BOLD, 48);
                g2d.setFont(font);
    
                FontRenderContext frc = g2d.getFontRenderContext();
                GlyphVector gv = font.createGlyphVector(frc, "Cats with hats");
                Rectangle2D box = gv.getVisualBounds();
    
                // Calclate the location of the text and offset the glyph shape...
                float x = (float) (getWidth() - box.getWidth()) / 2f;
                float y = (float) (((getHeight() - box.getHeight()) / 2f) + (-box.getY()));
    
                return gv.getOutline(x, y);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
    
                Shape shape = getTextShape();
    
                g2d.setColor(Color.BLACK);
                g2d.fill(shape);
                g2d.setColor(Color.RED);
                g2d.draw(shape);
    
                for (Rectangle box : boxes) {
                    g2d.setColor(Color.BLACK);
                    if (shape.intersects(box)) {
                        g2d.setColor(Color.RED);
                    }
                    g2d.draw(box);
                }
            }
    
        }
    
    }
    

    【讨论】:

    • 嘿,感谢您实际回答问题。我将在一个新项目中测试此代码,如果它有效,我将接受答案并将其实施到我的韩元中。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多