import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.applet.*;
public class GTApplet extends Applet implements MouseListener,
MouseMotionListener
{
enum mapNotations
{
FREE, OCCUPIED, BOOKED, RESERVED
};
private static final int GRID_PAINT_SIZE = 50;
private static final int MAP_RESOLUTION = GRID_PAINT_SIZE;
private static final int MAP_SIZE = 4 * 2;
private final mapNotations[][] map = new mapNotations[MAP_SIZE][MAP_SIZE];
private final int[][] markedMap = new int[MAP_SIZE][MAP_SIZE];
// Specify variables that will be needed everywhere, anytime here
// The font variable
Font bigFont, smallFont, smallestFont;
Color bgColor;
Color gridLineColor;
Color gridOccupiedColor;
Color startColor;
Color endColor;
Color helperLineColor;
Color markerColor;
Color textColor;
int startX = 50, startY = 50, endX = 50, endY = 50;
int markerDiameter = 6;
int mapMarkerDiameter = 26;
boolean isFreePath = false;
public void init()
{
// init the map
for (int x = 0; x < MAP_SIZE; x++)
{
for (int y = 0; y < MAP_SIZE; y++) { if (Math.random() > 0.2f)
{
map[x][y] = mapNotations.FREE;
} else
{
map[x][y] = mapNotations.OCCUPIED;
}
}
}
bigFont = new Font("Arial", Font.BOLD, 16);
bigFont = new Font("Arial", Font.BOLD, 12);
smallestFont = new Font("Calibri", Font.PLAIN, 10);
gridLineColor = Color.DARK_GRAY;
gridOccupiedColor = Color.LIGHT_GRAY;
startColor = Color.green;
endColor = Color.red;
helperLineColor = Color.black;
markerColor = Color.gray;
textColor = Color.DARK_GRAY;
bgColor = new Color(230, 231, 232);
setBackground(bgColor);
addMouseListener(this);
addMouseMotionListener(this);
}
public void mouseEntered(MouseEvent e)
{
// called when the pointer enters the applet's rectangular area
}
public void mouseExited(MouseEvent e)
{
// called when the pointer leaves the applet's rectangular area
}
public void mouseClicked(MouseEvent e)
{
// called after a press and release of a mouse button
// with no motion in between
// (If the user presses, drags, and then releases, there will be
// no click event generated.)
}
public void mousePressed(MouseEvent e)
{ // called after a button is pressed down
if (e.getButton() == MouseEvent.BUTTON1)
{
startX = e.getX();
startY = e.getY();
} else
{
endX = e.getX();
endY = e.getY();
}
resetMarkedMap();
isFreePath = isFreePath(startX, startY, endX, endY);
repaint();
// "Consume" the event so it won't be processed in the
// default manner by the source which generated it.
e.consume();
}
public void mouseReleased(MouseEvent e)
{ // called after a button is released
// repaint();
e.consume();
}
public void mouseMoved(MouseEvent e)
{ // called during motion when no buttons are down
// repaint();
e.consume();
}
public void mouseDragged(MouseEvent e)
{ // called during motion with buttons down
// repaint();
e.consume();
}
public void stop()
{
}
// just some simple and rude drawing
public void paint(Graphics g)
{
g.setColor(gridLineColor);
for (int x = 0; x < MAP_SIZE + 1; x++)
g.drawLine(x * GRID_PAINT_SIZE, 0, x * GRID_PAINT_SIZE, MAP_SIZE
* GRID_PAINT_SIZE);
for (int y = 0; y < MAP_SIZE + 1; y++)
g.drawLine(0, y * GRID_PAINT_SIZE, MAP_SIZE * GRID_PAINT_SIZE, y
* GRID_PAINT_SIZE);
g.setColor(gridOccupiedColor);
for (int x = 0; x < MAP_SIZE; x++)
{
for (int y = 0; y < MAP_SIZE; y++)
{
if (map[x][y] == mapNotations.OCCUPIED)
{
g.fillRect(x * GRID_PAINT_SIZE + 1,
y * GRID_PAINT_SIZE + 1, GRID_PAINT_SIZE - 1,
GRID_PAINT_SIZE - 1);
}
}
}
g.setColor(textColor);
g.setFont(smallestFont);
for (int x = 0; x < MAP_SIZE; x++)
{
for (int y = 0; y < MAP_SIZE; y++)
{
g.drawString("(" + x + "," + y + ")", x * GRID_PAINT_SIZE + 2,
y * GRID_PAINT_SIZE + 10);
}
}
g.setFont(bigFont);
g.drawString("Start: (" + startX + "," + startY + ")", 16, MAP_SIZE
* GRID_PAINT_SIZE + 30 + 10);
g.drawString("End: (" + endX + "," + endY + ")", 16, MAP_SIZE
* GRID_PAINT_SIZE + 48 + 10);
g.drawString("Is free path: " + isFreePath, 16, MAP_SIZE
* GRID_PAINT_SIZE + 48 + 18 + 10);
g.setFont(smallFont);
g.drawString("Start (map coords): (" + sx + "," + sy + ")", 16,
MAP_SIZE * GRID_PAINT_SIZE + 10 + 48 + 18 + 18 + 0 * 14);
g.drawString("End (map coords): (" + endX1 + "," + endY1 + ")", 16,
MAP_SIZE * GRID_PAINT_SIZE + 10 + 48 + 18 + 18 + 1 * 14);
g.drawString("Step (map coords): (" + stepX + "," + stepY + ")", 16,
MAP_SIZE * GRID_PAINT_SIZE + 10 + 48 + 18 + 18 + 2 * 14);
g.drawString("Dir: (" + dirX + "," + dirY + ")", 16, MAP_SIZE
* GRID_PAINT_SIZE + 10 + 48 + 18 + 18 + 3 * 14);
g.drawString("tDelta: (" + tDeltaX + "," + tDeltaY + ")", 16, MAP_SIZE
* GRID_PAINT_SIZE + 10 + 48 + 18 + 18 + 4 * 14);
g.drawString("sTMax: (" + sTMaxX + "," + sTMaxY + ")", 16, MAP_SIZE
* GRID_PAINT_SIZE + 10 + 48 + 18 + 18 + 5 * 14);
g.setColor(markerColor);
for (int x = 0; x < MAP_SIZE; x++)
{
for (int y = 0; y < MAP_SIZE; y++)
{
if (markedMap[x][y] == 1)
{
g.fillOval(x * GRID_PAINT_SIZE - mapMarkerDiameter / 2
+ GRID_PAINT_SIZE / 2, y * GRID_PAINT_SIZE
- mapMarkerDiameter / 2 + GRID_PAINT_SIZE / 2,
mapMarkerDiameter, mapMarkerDiameter);
}
}
}
g.setColor(startColor);
// draw start and end markers
g.drawOval(startX - markerDiameter / 2, startY - markerDiameter / 2,
markerDiameter, markerDiameter);
g.setColor(endColor);
// draw start and end markers
g.drawOval(endX - markerDiameter / 2, endY - markerDiameter / 2,
markerDiameter, markerDiameter);
g.setColor(helperLineColor);
g.drawLine(startX, startY, endX, endY);
}
public void resetMarkedMap()
{
for (int x = 0; x < MAP_SIZE; x++)
{
for (int y = 0; y < MAP_SIZE; y++)
{
markedMap[x][y] = 0;
}
}
}
int sx, sy, x, y, endX1, endY1, stepX, stepY;
float tDeltaX, tDeltaY;
float dirX, dirY;
float sTMaxX, sTMaxY;
public boolean isFreePath(float startX, float startZ, float endX, float endZ)
{
// calculate the direction of the ray (linear algebra)
dirX = (endX - startX);
dirY = (endZ - startZ);
float length = (float) Math.sqrt(dirX * dirX + dirY * dirY);
dirX /= length; // normalize the direction vector
dirY /= length;
tDeltaX = MAP_RESOLUTION / Math.abs(dirX); // how far we must move in the ray direction before we encounter a new voxel in x-direction
tDeltaY = MAP_RESOLUTION / Math.abs(dirY); // same but y-direction
// start voxel coordinates
sx = (int) (worldCoordToMapCoord(startX)); // use your transformer function here
sy = (int) (worldCoordToMapCoord(startZ));
// end voxel coordinates
endX1 = (int) (worldCoordToMapCoord(endX));
endY1 = (int) (worldCoordToMapCoord(endZ));
x = sx;
y = sy;
// decide which direction to start walking in
stepX = (int) Math.signum(dirX);
stepY = (int) Math.signum(dirY);
float tMaxX, tMaxY;
// calculate distance to first intersection in the voxel we start from
if(dirX < 0)
{
tMaxX = (mapToWorld(x)-startX) / dirX;
}else
{
tMaxX = (mapToWorld(x+1)-startX) / dirX;
}
if(dirY < 0)
{
tMaxY = (mapToWorld(y)-startY) / dirY;
}else
{
tMaxY = (mapToWorld(y+1)-startY) / dirY;
}
sTMaxX = tMaxX;
sTMaxY = tMaxY;
// check if first is occupied
if (isMapPositionOccupied(x, y)) // use your function here
return false;
boolean reachedX = false, reachedY = false;
while (true)
{
if (tMaxX < tMaxY) { tMaxX += tDeltaX; x += stepX; } else { tMaxY += tDeltaY; y += stepY; } if (stepX > 0.0f)
{
if (x >= endX1)
{
reachedX = true;
}
} else if (x <= endX1) { reachedX = true; } if (stepY > 0.0f)
{
if (y >= endY1)
{
reachedY = true;
}
} else if (y <= endY1)
{
reachedY = true;
}
if (isMapPositionOccupied(x, y))
{
return false;
}
if (reachedX && reachedY)
{
break;
}
}
return true;
}
private float mapToWorld(int coord)
{
return coord*MAP_RESOLUTION;
}
private float worldCoordToMapCoord(float coord)
{
return coord / MAP_RESOLUTION;
}
private boolean isMapPositionOccupied(int x, int y)
{
if(x < 0 || y < 0)
return true;
// save this for debug use
markedMap[x][y] = 1;
return map[x][y] == mapNotations.OCCUPIED;
}
} |