data structure for hit testing
Hi,
I'm experimenting with hit testing.
When I move the mouse cursor into a
hit test "box", I output a hit.
I have so far:
a JComponent W/MouseListener class Grid,
a hit test area, java.awt.Area: Grid.area,
and an array of "boxes" Rectangle[]: Grid.boxes.
All is well. In my Grid.mouseMoved method I am able
to determine if the mouse cursor is in the hit test area.
Now my current task is to determine from the mouse
cursor position - exactly which box I've hit so that
I can paint a symbol at the position of the box.
The question I would like to ask is: What type of
data structure can I use to store my hit test boxes in?
I think that trying to search my Grid.boxes array will
be very difficult and time consuming, and there is no
apparent (to me) way to find this information in Grid.area.
Can someone suggest better data structures or algorithms
for my current task?
Thanks.
Jeff Higgins
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Area;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class HitTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
Grid grid = new Grid();
grid.setPreferredSize(new Dimension(1000,1000));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 800, 600);
frame.add(grid);
frame.setVisible(true);
}
static class Grid extends JComponent
implements MouseMotionListener{
Area area = makeArea();
int[][] lines = makeGrid();
Rectangle[] boxes = makeHitBoxes();
public Grid(){addMouseMotionListener(this);}
public void paint(Graphics graphics) {
super.paint(graphics);
Graphics2D g = (Graphics2D) graphics;
for(int x=0;x<10;x++){
for(int y=0;y<10;y++){
g.drawLine(lines[x][0],
lines[x][1],
lines[x][2],
lines[x][3]);
g.drawLine(lines[y+10][0],
lines[y+10][1],
lines[y+10][2],
lines[y+10][3]);}}
for(int c=0;c<81;c++){
g.setColor(Color.red);
g.drawRect(boxes[c].x,
boxes[c].y,
boxes[c].width,
boxes[c].height);}
}
static Area makeArea(){
int[] r = new int[4];
Rectangle rect = new Rectangle();
Area area = new Area();
for(int x=1; x<10; x++){
for(int y=1; y<10; y++){
r[0] = x*100-15;
r[1] = y*100-15;
rect.setLocation(r[0],r[1]);
rect.setSize(30,30);
Area rectArea = new Area(rect);
area.add(rectArea);}
}return area;
}
static int[][] makeGrid(){
int[][] lines = new int[20][4];
lines[0][0] = 0;
lines[0][1] = 0;
lines[0][2] = 0;
lines[0][3] = 1000;
lines[10][0] = 0;
lines[10][1] = 0;
lines[10][2] = 1000;
lines[10][3] = 0;
for(int x=1; x<10; x++){
for(int y=1; y<10; y++){
lines[x][0] = x*100;
lines[x][1] = 0;
lines[x][2] = x*100;
lines[x][3] = 1000;
lines[y+10][0] = 0;
lines[y+10][1] = y*100;
lines[y+10][2] = 1000;
lines[y+10][3] = y*100;}
}return lines;
}
static Rectangle[] makeHitBoxes(){
int[] r = new int[4];
Rectangle[] boxes = new Rectangle[81];
int count = 0;
for(int x=1; x<10; x++){
for(int y=1; y<10; y++){
Rectangle rect = new Rectangle();
r[0] = x*100-15;
r[1] = y*100-15;
rect.setLocation(r[0],r[1]);
rect.setSize(30,30);
boxes[count] = rect;
count++;}}
return boxes;
}
public static void printHitPoints(Area area){
for(int i=0; i<100; i++){
for(int j=0; j<100; j++){
System.out.println(i + ":" + j + " "
+ area.contains(i,j));}}
}
public static void printGrid(int[][] lines){
for(int i=0; i<20; i++){
String orient = "horizontal line at ";
if(i>9) orient = "vertical line at ";
System.out.println(
orient
+ lines[i][0]
+ "," + lines[i][1]
+ " : " + lines[i][2]
+ "," + lines[i][3]);}
}
public static void printHitBoxes(Rectangle[] boxes){
for(Rectangle r : boxes){
System.out.println(r.toString());}
}
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {
if(area.contains(new Point(e.getX(),e.getY())))
System.out.println("Hit");
repaint();}
}
}