Hunt The Wumpus
<< Worm Game | FinalProjectsTrailIndex | Gridworld Dice Games >>
The code here has a fairly complete user interface that has a 3D Dodectrahedron (You need red-blue 3d glasses). To fuly implement the game, you need to make a Room class that can be filled with bats, pits and a smelly wumpus. Look for "//todo" in the code for details. The Room needs to be able to report if it has
- gold
- a bottomless pit
- bats that transport the player to a random room
- a deadly wumpus that will eat the player
You would also need to a write a method in the WumpusApplet that will randomly place these hazards in the the 20 Rooms.
The UI demonstrates rotation around axes controlled by a click and drag, and double buffering that removes a flicker that occurs in Windows.
For a complete description of this classic game see the Wikipeadia article
To see a working demo of the user interface, click here
WumpusApplet.java
import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
public class WumpusApplet extends Applet implements ActionListener, MouseMotionListener, MouseListener
{
private Button forward,turnL, turnR, grab, shoot,help, look;
private String direction, message, message2, contents, turn;
private int loc, nextLoc, gold;
private Dodectrahedron d;
private ArrayList<Button> btns;
private Rectangle view1, view2;
//double buffering to remove Windows flicker:
private Image screen2;
private Graphics g2;
// mouse drag to rotate
private int startX = -1, startY = -1;
private int curX = -1, curY = -1;
private boolean inDrag=false;
private int yAng, xAng, dX, dY, deaths, kills;
private ArrayList<Integer> shot,visited;
private static final boolean ORTHO = true;
private static final double LEFT = 0;// Degree separation for left view
private static final double RIGHT = 4.0;// Degree separation for right view
private static final double LOW = .14; // HEIGHT of spikes and Dot
private static final Color cyan = new Color(0, 255,255,50);
private static final Color red = new Color (255, 0,0,50);
//todo: private Room[] rooms;
public void init(){
setUpGame();
int deaths=0;
int kills=0;
gold=0;
this.setLayout(new FlowLayout());
setUpButtons();
view1= new Rectangle(425, 300, 250,250 );
view2= new Rectangle(75, 300, 250,250 );
yAng=0;//rot around yAxis
xAng=0;//rot around xAxis
dX=dY=0;//slope of the mouse dragging
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
private void setUpGame() {
direction="straight ahead";
contents ="You seem to be in an empty room";
message="Hunt the Wumpus!";
message2="";
turn="left";
loc=0;
nextLoc=0;
d=new Dodectrahedron();
shot=new ArrayList<Integer>();
visited=new ArrayList<Integer>();
//todo: Initialize 20 rooms
//todo: Randomly fill the rooms with bats, pits and a wupus.
}
private void setUpButtons() {
forward = new Button("Go Forward");
turnL = new Button("Turn Left");
turnR = new Button("Turn Right");
grab = new Button("Grab");
shoot = new Button("Shoot Arrow");
help = new Button("Help");
look = new Button("Look");
btns = new ArrayList<Button>();
btns.add(forward);
btns.add(turnL);
btns.add(turnR);
btns.add(grab);
btns.add(shoot);
btns.add(help);
btns.add(look);
for(Button b:btns){
b.addActionListener(this);
add(b);
}
}
public void paint(Graphics g){
int width=getWidth();
int height=getHeight();
screen2 = createImage(width,height);
g2 = screen2.getGraphics();
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, width, height);
g2.setColor(Color.BLACK);
g2.drawString(message, 20, 120);
g2.drawString(message2, 20, 140);
g2.drawString("You are facing "+direction, 20, 180);
g2.drawString(contents, 20, 200);
g2.drawString("You have "+gold+" gold", 20, 220);
g2.drawString("You have been killed "+deaths+" times", 20, 240);
g2.drawString("You have killed a wumpus "+gold+" times", 20, 260);
g2.drawString("y axis angle ="+(d.getyAxisAngle()), 350, 260);
g2.drawString("x axis angle ="+d.getxAxisAngle(), 350, 280);
g2.drawRect(view1.x, view1.y, view1.width, view1.height);
g2.drawRect(view2.x, view2.y, view2.width, view2.height);
drawStereo(g2, view1);
drawOrtho(g2, view2);
//draw g2 to screen
g.drawImage(screen2, 0,0,this);
}
private void drawStereo(Graphics g, Rectangle view) {
//left cyan
g.setColor(cyan);
for (int i=0; i<12; i++){
g.drawPolygon(d.getFace(i).getOrthoPolygon(view, yAng+dY, xAng+dX));
}
d.drawEdges(g, view, ORTHO);
d.spikeVertex(g, view, 0, LOW, ORTHO, LEFT);
d.drawDot(g, view, loc, LOW, ORTHO, LEFT);
d.point2Vertex(g, view, loc, nextLoc, ORTHO, LEFT);
//right red
g.setColor(red);
for (int i=0; i<12; i++){
g.drawPolygon(d.getFace(i).getOrthoPolygon(view, yAng+dY+RIGHT, xAng+dX));
}
//d.drawEdgesOrtho(g, screenR);
d.spikeVertex(g, view, loc, 1.0, ORTHO, RIGHT);
d.drawDot(g, view, loc, LOW, ORTHO, RIGHT);
d.point2Vertex(g, view, loc,nextLoc, ORTHO, RIGHT);
}
private void drawOrtho(Graphics g, Rectangle view) {
for (int i=0; i<12; i++){
g.setColor(d.getFace(i).getColor());
g.fillPolygon(d.getFace(i).getOrthoPolygon(view, yAng+dY, xAng+dX));
}
g.setColor(Color.BLACK);
d.drawEdges(g, view, ORTHO);
d.spikeVertex(g, view, loc, LOW, ORTHO, LEFT);
d.spikeVertex(g, view, loc,LOW, ORTHO, LEFT);
d.drawDot(g, view, loc, LOW, ORTHO, LEFT);
d.point2Vertex(g, view, loc, nextLoc, ORTHO, LEFT);
//indicate the rooms you shot into with red
g.setColor(Color.MAGENTA);
for(Integer i:shot){
d.spikeVertex(g, view, i, LOW, ORTHO, LEFT);
}
//indicate the rooms you visited
g.setColor(Color.GREEN);
for(Integer i:visited){
d.spikeVertex(g, view, i, LOW, ORTHO, LEFT);
}
}
public void update(Graphics g){
paint(g);
}
@Override
public void mouseDragged(MouseEvent e) {
curX=e.getX();
curY=e.getY();
if (inDrag){
dY = (startX-curX)/2;//y axis delta
dX = (startY-curY)/2;//x axis delta
d.setyAxisAngle((yAng+dY)%360);
d.setxAxisAngle((xAng+dX)%360);
repaint();
}
}
@Override
public void mouseMoved(MouseEvent e) {}
@Override
public void mouseClicked(MouseEvent e) { }
@Override
public void mousePressed(MouseEvent e) {
inDrag=true;
startX = curX = e.getX();
startY = curY = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {
inDrag=false;
xAng+=dX;
yAng+=dY;
dX=dY=0;
repaint();
}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
if(src==grab){
//todo: use room method getGold
message="Nothing to Grab here.";
message2="You have "+gold+" gold.";
}else if(src==turnL){
message="You turn left.";
turn="left";
nextLoc=d.getLeft(loc, nextLoc);
direction=" a passage to room "+nextLoc;
//todo: use Room method hasWupus(nextLoc)-- message2="You smell a wumpus"
//todo: use Room method hasPit(nextLoc)--message2="You fell a breeze"
//todo: use Room method hasBats(nextLoc)==message2="You hear flapping wings"
message2="";
}else if(src==turnR){
message="You turn right.";
turn="right";
nextLoc=d.getRight(loc, nextLoc);
direction=" a passage to room "+nextLoc;
//todo: use Room method hasWupus(nextLoc)-- message2="You smell a wumpus"
//todo: use Room method hasPit(nextLoc)--message2="You fell a breeze"
//todo: use Room method hasBats(nextLoc)==message2="You hear flapping wings"
message2="";
}else if(src==look){
//todo:check for contents in nextLoc
// you might smell a wumpus, feel a draft, or hear bats
//todo: use Room method hasWupus(nextLoc)-- message2="You smell a wumpus"
//todo: use Room method hasPit(nextLoc)--message2="You fell a breeze"
//todo: use Room method hasBats(nextLoc)==message2="You hear flapping wings"
message2="";
message="You look around. You see a sign with the number "+loc+" on the wall";
message2="";
}else if(src==help){
message= "You want to find gold and kill the wupus with your crooked arrows.";
message2 ="Avoid drafty bottomless pits, bats that relocate you, and going into a wumpus infested room.";
}else if (src==shoot){
message="You shoot in the direction of room "+nextLoc;
int[] rooms = d.getFaceNodes(loc, nextLoc, turn);
if (rooms!=null){
for(int i:rooms)
shot.add(i);
//todo: check to see if you killed the wumpus
// needs Room method hasWumpus()
message2="You may have shot something";
}else{
message2="Without aim you wasted an arrow";
}
}else if (src==forward){
if (loc!=nextLoc){
message="You go down the passage to room "+nextLoc;
//todo: use Room method hasWupus(nextLoc)-- message2="You are eaten by wumpus"
//todo: use Room method hasPit(nextLoc)--message2="You fell into a bottomless pit"
//todo: use Room method hasBats(nextLoc)==message2="Bats fly you to a random room"
message2="";
visited.add(loc);
}else{
message="You walk into a wall and hit your head";
}
//change current room
loc=nextLoc;
message2="";
direction="straight ahead";
}
//todo: update graphics
repaint();
}
}
Vertex.java
import java.awt.Point;
import java.awt.Rectangle;
public class Vertex implements Comparable
{
private double x,y,z;
public static final double CamX=0;//3d viewpoint coords
public static final double CamY=0;//3d viewpoint coords
public static final double CamZ=-3;//3d viewpoint coords
//public int xfac=90, zfac=90;
public static final double RADIANS=Math.PI/180.0;//degree to radian conversion
public Vertex(double x, double y, double z){
this.x=x;
this.y=y;
this.z=z;
}
public boolean equals(Vertex o)
{
return x==o.getX() && y==o.getY() && z==o.getZ();
}
public double getZ() {
return z;
}
public double getY() {
return y;
}
public double getX() {
return x;
}
@Override
public int compareTo(Object o) {
return (int)(Math.round(distance((Vertex)o)));
}
public double distance(Vertex o) {
return Math.sqrt(
Math.pow(x-o.getX(), 2)+
Math.pow(y-o.getY(), 2)+
Math.pow(z-o.getZ(), 2)
);
}
public int screenX(Rectangle r){
double x0 = r.width/2*(x - CamX) /(z-CamZ);
return r.x+r.width/2+(int)Math.round(x0);
}
public int screenY(Rectangle r){
double y0 = r.height/2*(y - CamY) /(z-CamZ);
return r.y+r.height/2-(int)Math.round(y0);
}
public Point screenXY(Rectangle r, double yAxis, double xAxis){
double a = 2*yAxis*RADIANS;
double b = 2*xAxis*RADIANS;
//rotation around y axis
double z0 = z*Math.cos(a)-x*Math.sin(a);
double x0 = z*Math.sin(a)+x*Math.cos(a);
//rotation around x axis
double y0 = y*Math.cos(b)-z0*Math.sin(b);
double z1 = y*Math.sin(b)+z0*Math.cos(b);
//projection
double px = r.width/2*(x0 - CamX) /(z1-CamZ);
double py = r.height/2*(y0 - CamY) /(z1-CamZ);
int sy = r.y+r.height/2-(int)Math.round(py);
int sx = r.x+r.width/2+(int)Math.round(px);
return new Point(sx,sy);
}
public Point orthoXY(Rectangle r, double yAxis, double xAxis){
double a = 2*yAxis*RADIANS;
double b = 2*xAxis*RADIANS;
//rotation around y axis
double z0 = z*Math.cos(a)-x*Math.sin(a);
double x0 = z*Math.sin(a)+x*Math.cos(a);
//rotation around x axis
double y0 = y*Math.cos(b)-z0*Math.sin(b);
double z1 = y*Math.sin(b)+z0*Math.cos(b);
//orthogonal projection of x0,y0,z1
double theta= Math.PI/8;
double phi= -1*Math.PI/15;
double s=r.width/4;
double xf=s*.89;
double zf=s*.68;
double px = xf*Math.cos(phi)*(x0 - CamX) + zf*Math.cos(theta)*(z1-0);
double py = s*(y0 - CamY) + zf*Math.sin(theta)*(z1-0)+xf*Math.sin(phi)*(x0 - CamX);
int sy = r.y+r.height/2-(int)Math.round(py);
int sx = r.x+r.width/2+(int)Math.round(px);
return new Point(sx,sy);
}
/**
* change the point by rotation around the y axis
* @param degrees
*/
public void rotateAxisY(double degrees){
double a = 2*degrees*RADIANS;
double z0 = z*Math.cos(a)-x*Math.sin(a);
double x0 = z*Math.sin(a)+x*Math.cos(a);
z=z0;
x=x0;
}
public void rotateAxisX(double degrees){
double a = 2*degrees*RADIANS;
double y0 = y*Math.cos(a)-z*Math.sin(a);
double z0 = y*Math.sin(a)+z*Math.cos(a);
y=y0;
z=z0;
}
public static Vertex midpoint(Vertex v1, Vertex v2){
double xm = 0.5*(v1.getX()+v2.getX());
double ym = 0.5*(v1.getY()+v2.getY());
double zm = 0.5*(v1.getZ()+v2.getZ());
return new Vertex(xm,ym,zm);
}
public static Vertex spike(Vertex v1, Vertex v2){
double xm = 0.5*(v1.getX()+v2.getX());
double ym = 0.5*(v1.getY()+v2.getY());
double zm = 0.5*(v1.getZ()+v2.getZ());
return new Vertex(v2.getX()+xm/2,v2.getY()+ym/2,v2.getZ()+zm/2);
}
/**
*
* @param v1
* @param percent of vertex to origin
* @return a vertex a percentage away from origin
*/
public static Vertex spike(Vertex v1, double percent){
double xm = percent*(v1.getX());
double ym = percent*(v1.getY());
double zm = percent*(v1.getZ());
return new Vertex(v1.getX()+xm,v1.getY()+ym,v1.getZ()+zm);
}
public String toString(){
return String.format("(%.3f, %.3f, %.3f)", x,y,z);
}
}
Face.java
import java.awt.Color;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
public class Face implements Comparable<Face>
{
private Vertex[] v;
private Color color;
public Face(Vertex v0, Vertex v1, Vertex v2, Vertex v3, Vertex v4){
setColor(Color.WHITE);
v = new Vertex[5];
v[0]=v0;
v[1]=v1;
v[2]=v2;
v[3]=v3;
v[4]=v4;
}
public Polygon polygon(Rectangle screen, double scale){
Polygon p = new Polygon();
for (int i=0; i<5; i++)
p.addPoint(v[i].screenX(screen), v[i].screenY(screen));
return p;
}
public String toString(){
String s="[";
for (Vertex n:v)
s+=n.toString()+" ";
return s+"]";
}
@Override
public int compareTo(Face o) {
return (int)(100.0*this.distanceToViewpoint()-100*o.distanceToViewpoint());
}
public double distanceToViewpoint(){
return center().distance(new Vertex(Vertex.CamX, Vertex.CamY, Vertex.CamZ));
}
public Vertex center(){
double x,y,z;
x=y=z=0;
for(Vertex n:v){
x+=n.getX();
y+=n.getY();
z+=n.getZ();
}
return new Vertex(x/5.0, y/5.0, z/5.0);
}
public Polygon getPolygon(Rectangle screen, double yAxis, double xAxis){
Polygon p = new Polygon();
for (int i=0; i<5; i++){
Point pt = v[i].screenXY(screen, yAxis, xAxis);
p.addPoint(pt.x, pt.y);
}
return p;
}
public Polygon getOrthoPolygon(Rectangle screen, double yAxis, double xAxis){
Polygon p = new Polygon();
for (int i=0; i<5; i++){
Point pt = v[i].orthoXY(screen, yAxis, xAxis);
p.addPoint(pt.x, pt.y);
}
return p;
}
public Color getColor() {
return color;
}
public Color getCyan() {
return new Color(0, 0, color.getBlue(), color.getTransparency());
}
public Color getRed() {
return new Color(color.getRed(),0, 0, color.getTransparency());
}
public void setColor(Color color) {
this.color = new Color(color.getRed(), color.getGreen(), color.getBlue(), 128);
}
}
Dodectrahedron.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
public class Dodectrahedron
{
private Vertex[] v;
private Face[] f;
private int [][] adjacentNodes;
private double yAxisAngle, xAxisAngle;
public static final double PI_5 = 2.0*Math.PI/5.0;
public static final double PHI=1.618033988749894848204586834365638;
public Dodectrahedron(){
v = new Vertex[20];
v[0]=new Vertex(1,1,1);
v[1]=new Vertex(1,1,-1);
v[2]=new Vertex(1,-1,1);
v[3]=new Vertex(1,-1,-1);
v[4]=new Vertex(-1,1,1);
v[5]=new Vertex(-1,1,-1);
v[6]=new Vertex(-1,-1,1);
v[7]=new Vertex(-1,-1,-1);
v[8]=new Vertex(0,1.0/PHI,PHI);//green
v[9]=new Vertex(0,1.0/PHI,-PHI);
v[10]=new Vertex(0,-1.0/PHI,PHI);
v[11]=new Vertex(0,-1.0/PHI,-PHI);
v[12]=new Vertex(PHI,0,1/PHI);//red
v[13]=new Vertex(PHI,0,-1/PHI);
v[14]=new Vertex(-PHI,0,1/PHI);
v[15]=new Vertex(-PHI,0,-1/PHI);
v[16]=new Vertex(1.0/PHI,PHI,0);//blu
v[17]=new Vertex(1.0/PHI,-PHI,0);
v[18]=new Vertex(-1.0/PHI,PHI,0);
v[19]=new Vertex(-1.0/PHI,-PHI,0);
f = new Face[12];
f[0] = new Face(v[18], v[16], v[1], v[9],v[5]);//ok
f[1] = new Face(v[18], v[16], v[0], v[8],v[4]);//ok
f[2] = new Face(v[16], v[1], v[13], v[12],v[0]);
f[3] = new Face(v[1], v[9], v[11], v[3],v[13]);
f[4] = new Face(v[9], v[5], v[15], v[7],v[11]);
f[5] = new Face(v[5], v[18], v[4], v[14],v[15]);
f[6] = new Face(v[10], v[2], v[17], v[19],v[6]);
f[7] = new Face(v[10], v[2], v[12], v[0],v[8]);
f[8] = new Face(v[2], v[17], v[3], v[13],v[12]);
f[9] = new Face(v[17], v[19], v[7], v[11],v[3]);
f[10] = new Face(v[19], v[6], v[14], v[15],v[7]);
f[11] = new Face(v[6], v[10], v[8], v[4],v[14]);
for (Face side:f)
side.setColor(randomColor());
this.adjacentNodes = new int [20][3];
//clockwise
initNode(0,8,12,16);
initNode(1,16,13, 9);
initNode(2,12,10, 17);
initNode(3,13, 17, 11);
initNode(4,18, 14, 8);
initNode(5,18, 9,15);
initNode(6,14,19, 10);
initNode(7,15,11,19);
initNode(8,4,10,0);
initNode(9,5,1,11);
initNode(10,8,6,2);
initNode(11,3,7,9);
initNode(12,0,2,13);
initNode(13,1,12,3);
initNode(14,4,15,6);
initNode(15,5,7,14);
initNode(16,0,1,18);
initNode(17,3,2,19);
initNode(18,16,5,4);
initNode(19,7,17,6);
}
public void nodeTest(Graphics g, Rectangle screen, int n){
g.setColor(Color.BLACK);
for(int i=0; i<3;i++)
connect(g, n, adjacentNodes[n][i], screen, true);
}
private void initNode(int n, int v0, int v1,int v2){
adjacentNodes[n][0]=v0;
adjacentNodes[n][1]=v1;
adjacentNodes[n][2]=v2;
}
/**
* from a node, facing a node get the left node
* @return -1 if not possible to face from the node from that node error
*/
public int getLeft(int from, int facing){
int currentIndex=0;
if(from==facing)// select first if same node
facing=adjacentNodes[from][0];
while (currentIndex<3 && facing!=adjacentNodes[from][currentIndex])
currentIndex++;
if (adjacentNodes[from][currentIndex]!=facing)
return -1;
int i=(currentIndex-1+3)%3;
return adjacentNodes[from][i];
}
/**
* from a node, facing a node get the left node
* @return -1 if not possible to face from the node from that node error
*/
public int getRight(int from, int facing){
int currentIndex=0;
if(from==facing)// select first if same node
facing=adjacentNodes[from][0];
while (currentIndex<3 && facing!=adjacentNodes[from][currentIndex])
currentIndex++;
if (adjacentNodes[from][currentIndex]!=facing)
return -1;
int i=(currentIndex+1+3)%3;
return adjacentNodes[from][i];
}
/**
* Returns the array of 5 nodes of the pentagan from a node facing a node.
* @param from
* @param facing
* @param leftOrRight
* @return null if not facing properly
*/
public int[] getFaceNodes(int from, int facing, String leftOrRight){
if (from==facing)
return null;
if (getRight(from,facing)==-1)
return null;
int[] p=new int[5];
p[0]=from;
p[1]=facing;
if (leftOrRight.equalsIgnoreCase("left")){
for (int i=2; i<5;i++)
p[i]=getRight(p[i-1],p[i-2]);
}else{
for (int i=2; i<5;i++)
p[i]=getLeft(p[i-1],p[i-2]);
}
return p;
}
public Color randomColor(){
return new Color((int)(255*Math.random()), (int)(255*Math.random()), (int)(255*Math.random()));
}
public void rotateY(double yAxisDeg){
for (Vertex n:v)
n.rotateAxisY(yAxisDeg);
}
public void rotateX( double xAxisDeg){
for (Vertex n:v)
n.rotateAxisX(xAxisDeg);
}
public Face getFace(int i){ return f[i]; }
public Face[] getFaces(){ return f; }
public Vertex getVertex(int i){ return v[i]; }
public double getyAxisAngle() {
return yAxisAngle;
}
public void setyAxisAngle(double yAxisAngle) {
this.yAxisAngle = yAxisAngle;
}
public double getxAxisAngle() {
return xAxisAngle;
}
public void setxAxisAngle(double xAxisAngle) {
this.xAxisAngle = xAxisAngle;
}
public void drawEdges(Graphics g, Rectangle screen, boolean ortho){
connect(g, 18, 16, screen, ortho);
connect(g, 16, 1, screen, ortho);
connect(g, 1, 9, screen, ortho);
connect(g, 9, 5, screen, ortho);
connect(g, 5, 18, screen, ortho);
connect(g, 16, 0, screen, ortho);
connect(g, 0, 8, screen, ortho);
connect(g, 8, 4, screen, ortho);
connect(g, 4, 18, screen, ortho);
connect(g, 0, 12, screen, ortho);
connect(g, 12, 13, screen, ortho);
connect(g, 13, 1, screen, ortho);
connect(g, 13, 3, screen, ortho);
connect(g, 3, 11, screen, ortho);
connect(g, 11, 9, screen, ortho);
connect(g, 11, 7, screen, ortho);
connect(g, 7, 15, screen, ortho);
connect(g, 15, 5, screen, ortho);
connect(g, 15, 14, screen, ortho);
connect(g, 14, 4, screen, ortho);
connect(g, 10, 8, screen, ortho);
connect(g, 2, 12, screen, ortho);
connect(g, 17, 3, screen, ortho);
connect(g, 19, 7, screen, ortho);
connect(g, 6, 14, screen, ortho);
connect(g, 10, 2, screen, ortho);
connect(g, 2, 17, screen, ortho);
connect(g, 17, 19, screen, ortho);
connect(g, 19, 6, screen, ortho);
connect(g, 6, 10, screen, ortho);
}
public void drawCenter2Vertex(Graphics g, Rectangle area, int i,boolean ortho, double offset){
Vertex o=new Vertex(0,0,0);
Point p1,p2;
if(ortho){
p1=o.orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(i).orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
}else{
p1=o.screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(i).screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
}
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
public void point2Vertex(Graphics g, Rectangle area, int from, int to, boolean ortho, double offset){
Vertex o=Vertex.spike(getVertex(from), .25);
Point p1,p2, p3;
if(ortho){
p1=Vertex.midpoint(getVertex(from), getVertex(to)).orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(from).orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
p3=o.orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
}else{
p1=Vertex.midpoint(getVertex(from), getVertex(to)).screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(from).screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
p3=o.screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
}
Polygon flag = new Polygon();
flag.addPoint(p1.x, p1.y);
flag.addPoint(p2.x, p2.y);
flag.addPoint(p3.x, p3.y);
g.fillPolygon(flag);
}
/**
*
* @param g
* @param area
* @param i the node
* @param percent how long the spike
* @param ortho whether or not ortho or perspectve projectoin
* @param offset rotation offset for stereo use
*/
public void spikeVertex(Graphics g, Rectangle area, int i, double percent, boolean ortho, double offset){
Vertex o=Vertex.spike(getVertex(i), percent);
Point p1,p2;
if(ortho){
p1=o.orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(i).orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
}else{
p1=o.screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(i).screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
}
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
public void connect(Graphics g,int i, int j, Rectangle screen, boolean ortho, double offset){
Point p1,p2;
if (ortho){
p1=getVertex(i).orthoXY(screen, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(j).orthoXY(screen, getyAxisAngle()+offset, getxAxisAngle());
}else {
p1=getVertex(i).screenXY(screen, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(j).screenXY(screen, getyAxisAngle()+offset, getxAxisAngle());
}
g.drawLine(p1.x, p1.y, p2.x, p2.y );
}
public void connect(Graphics g, int i, int j, Rectangle screen, boolean ortho){
connect(g,i,j,screen,ortho,0);
}
public void drawDot(Graphics g, Rectangle area, int i, double percent, boolean ortho, double offset){
Vertex o=Vertex.spike(getVertex(i), percent);
Point p1,p2;
if(ortho){
p1=o.orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(i).orthoXY(area, getyAxisAngle()+offset, getxAxisAngle());
}else{
p1=o.screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
p2=getVertex(i).screenXY(area, getyAxisAngle()+offset, getxAxisAngle());
}
int size=(int)Math.round(Math.sqrt(Math.pow(p1.x-p2.x,2)+Math.pow(p1.y-p2.y,2)));
size=Math.max(5, size);
g.fillOval(p1.x-size, p1.y-size, 2*size, 2*size);
}
}
