为了账号安全,请及时绑定邮箱和手机立即绑定

检查矩形是否与文本相交

检查矩形是否与文本相交

梵蒂冈之花 2021-11-11 13:21:50
我有一个叫做“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();但是它不起作用,我想是因为位置,但是我不知道如何在其中添加位置。谢谢。
查看完整描述

1 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

您可能需要做的一件事是将GlyphVector或翻译成Rectangle正确的上下文。


我的意思是, the GlyphVectoronly 代表原点处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);

            }

        }


    }


}



查看完整回答
反对 回复 2021-11-11
  • 1 回答
  • 0 关注
  • 149 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信