[英]Checking if a rectangle intersects text
I have a class called 'MapObject' which allows you to define what it is, what it does.我有一个叫做“MapObject”的类,它允许你定义它是什么,它做什么。 I have recently added text to this, and it works fine however the collisions is a rectangle, which in some scenarios isn't horrible, however I would prefer to have a collision box matching the text (aka check if a 1x1 rectangle collides with the text but can still be inbetween letters)我最近为此添加了文本,它工作正常,但是碰撞是一个矩形,在某些情况下并不可怕,但是我更喜欢有一个与文本匹配的碰撞框(也就是检查 1x1 矩形是否与文本,但仍然可以在字母之间)
I have tried the following:我尝试了以下方法:
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();
However it just doesn't work, I imagine because of the location, however I don't know how to add a location into it.但是它不起作用,我想是因为位置,但是我不知道如何在其中添加位置。 Thanks.谢谢。
One of the things you probably need to do is translate either the GlyphVector
or Rectangle
to the correct context.您可能需要做的一件事是将GlyphVector
或Rectangle
转换为正确的上下文。
What I mean is, the GlyphVector
only represents the text at a origin point of 0x0
, so if the text is displayed somewhere else on the screen, then you're not getting the correct representation.我的意思是, GlyphVector
仅表示原点0x0
的文本,因此如果文本显示在屏幕上的其他位置,那么您将无法获得正确的表示。
Luckily, someone actually thought about this use case and provided some functionality to do it.幸运的是,有人真的考虑过这个用例并提供了一些功能来实现它。 See GlyphVector#getOutline(float, float)
for more details.有关更多详细信息GlyphVector#getOutline(float, float)
请参阅GlyphVector#getOutline(float, float)
。
You could then use it something like...然后你可以使用它像......
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);
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.