diff --git a/AbstractNode.java b/AbstractNode.java
deleted file mode 100644
index 48ab821..0000000
--- a/AbstractNode.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-/**
- * This class represents an AbstractNode. It has all the appropriate fields as well
- * as getter and setter to be used by the A* algorithm.
- *
- *
- * An AbstractNode
has x- and y-coordinates and can be walkable or not.
- * A previous AbstractNode may be set, as well as the
- * fCosts
, gCosts
and hCosts
.
- *
- *
- * fCosts
: gCosts
+ hCosts
- *
- * gCosts
: calculated costs from start AbstractNode to this AbstractNode
- *
- * hCosts
: estimated costs to get from this AbstractNode to end AbstractNode
- *
- *
- * A subclass has to override the heuristic function
- *
- * sethCosts(AbstractNode endAbstractNode)
- *
- * @see ExampleNode#sethCosts(AbstractNode endNode) example Implementation using manhatten method
- *
- *
- * @version 1.0
- */
-public abstract class AbstractNode {
-
- /** costs to move sideways from one square to another. */
- protected static final float BASICMOVEMENTCOST = 10;
- /** costs to move diagonally from one square to another. */
- protected static final float DIAGONALMOVEMENTCOST = 14;
-
- protected float xPosition;
- protected float yPosition;
- protected boolean walkable;
-
- // for pathfinding:
-
- /** the previous AbstractNode of this one on the currently calculated path. */
- protected AbstractNode previous;
-
- /** weather or not the move from previous to this AbstractNode is diagonally. */
- protected boolean diagonally;
-
- /** optional extra penalty. */
- protected float movementPanelty;
-
- //private float fCosts; // g + h costs
-
- /** calculated costs from start AbstractNode to this AbstractNode. */
- protected float gCosts;
-
- /** estimated costs to get from this AbstractNode to end AbstractNode. */
- protected float hCosts;
-
- /**
- * constructs a walkable AbstractNode with given coordinates.
- *
- * @param xPosition
- * @param yPosition
- */
- public AbstractNode(float xPosition, float yPosition) {
- this.xPosition = xPosition;
- this.yPosition = yPosition;
- this.walkable = true;
- this.movementPanelty = 0;
- }
-
- /**
- * returns weather or not the move from the previousAbstractNode
was
- * diagonally. If it is not diagonal, it is sideways.
- *
- * @return
- */
- public boolean isDiagonaly() {
- return diagonally;
- }
-
- /**
- * sets weather or not the move from the previousAbstractNode
was
- * diagonally. If it is not diagonal, it is sideways.
- *
- * @param isDiagonaly
- */
- public void setIsDiagonaly(boolean isDiagonaly) {
- this.diagonally = isDiagonaly;
- }
-
- /**
- * sets x and y coordinates.
- *
- * @param x
- * @param y
- */
- public void setCoordinates(float x, float y) {
- this.xPosition = x;
- this.yPosition = y;
- }
-
- /**
- * @return the xPosition
- */
- public float getxPosition() {
- return xPosition;
- }
-
- /**
- * @return the yPosition
- */
- public float getyPosition() {
- return yPosition;
- }
-
- /**
- * @return the walkable
- */
- public boolean isWalkable() {
- return walkable;
- }
-
- /**
- * @param walkable the walkable to set
- */
- public void setWalkable(boolean walkable) {
- this.walkable = walkable;
- }
-
- /**
- * returns the node set as previous node on the current path.
- *
- * @return the previous
- */
- public AbstractNode getPrevious() {
- return previous;
- }
-
- /**
- * @param previous the previous to set
- */
- public void setPrevious(AbstractNode previous) {
- this.previous = previous;
- }
-
- /**
- * sets a general penalty for the movement on this node.
- *
- * @param movementPanelty the movementPanelty to set
- */
- public void setMovementPanelty(float movementPanelty) {
- this.movementPanelty = movementPanelty;
- }
-
- /**
- * returns gCosts
+ hCosts
.
- *
- *
- *
- * @return the fCosts
- */
- public float getfCosts() {
- return gCosts + hCosts;
- }
-
- /**
- * returns the calculated costs from start AbstractNode to this AbstractNode.
- *
- * @return the gCosts
- */
- public float getgCosts() {
- return gCosts;
- }
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode.
- *
- * @param gCosts the gCosts to set
- */
- private void setgCosts(float gCosts) {
- this.gCosts = gCosts + movementPanelty;
- }
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode given the previous AbstractNode as well as the basic cost
- * from it to this AbstractNode.
- *
- * @param previousAbstractNode
- * @param basicCost
- */
- public void setgCosts(AbstractNode previousAbstractNode, float basicCost) {
- setgCosts(previousAbstractNode.getgCosts() + basicCost);
- }
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode given the previous AbstractNode.
- *
- * It will assume BASICMOVEMENTCOST
as the cost from
- * previousAbstractNode
to itself if the movement is not diagonally,
- * otherwise it will assume DIAGONALMOVEMENTCOST
.
- * Weather or not it is diagonally is set in the Map class method which
- * finds the adjacent AbstractNodes.
- *
- * @param previousAbstractNode
- */
- public void setgCosts(AbstractNode previousAbstractNode) {
- if (diagonally) {
- setgCosts(previousAbstractNode, DIAGONALMOVEMENTCOST);
- } else {
- setgCosts(previousAbstractNode, BASICMOVEMENTCOST);
- }
- }
-
- /**
- * calculates - but does not set - g costs.
- *
- * It will assume BASICMOVEMENTCOST
as the cost from
- * previousAbstractNode
to itself if the movement is not diagonally,
- * otherwise it will assume DIAGONALMOVEMENTCOST
.
- * Weather or not it is diagonally is set in the Map class method which
- * finds the adjacent AbstractNodes.
- *
- * @param previousAbstractNode
- * @return gCosts
- */
- public float calculategCosts(AbstractNode previousAbstractNode) {
- if (diagonally) {
- return (previousAbstractNode.getgCosts()
- + DIAGONALMOVEMENTCOST + movementPanelty);
- } else {
- return (previousAbstractNode.getgCosts()
- + BASICMOVEMENTCOST + movementPanelty);
- }
- }
-
- /**
- * calculates - but does not set - g costs, adding a movementPanelty.
- *
- * @param previousAbstractNode
- * @param movementCost costs from previous AbstractNode to this AbstractNode.
- * @return gCosts
- */
- public float calculategCosts(AbstractNode previousAbstractNode, float movementCost) {
- return (previousAbstractNode.getgCosts() + movementCost + movementPanelty);
- }
-
- /**
- * returns estimated costs to get from this AbstractNode to end AbstractNode.
- *
- * @return the hCosts
- */
- public float gethCosts() {
- return hCosts;
- }
-
- /**
- * sets hCosts.
- *
- * @param hCosts the hCosts to set
- */
- protected void sethCosts(float hCosts) {
- this.hCosts = hCosts;
- }
-
- /**
- * calculates hCosts for this AbstractNode to a given end AbstractNode.
- * Uses Manhatten method.
- *
- * @param endAbstractNode
- */
- public abstract void sethCosts(AbstractNode endAbstractNode);
-
-
- /*
- * @return the movementPanelty
- */
- private float getMovementPanelty() {
- return movementPanelty;
- }
-
- /**
- * returns a String containing the coordinates, as well as h, f and g
- * costs.
- *
- * @return
- */
- @Override
- public String toString() {
- return "(" + getxPosition() + ", " + getyPosition() + "): h: "
- + gethCosts() + " g: " + getgCosts() + " f: " + getfCosts();
- }
-
- /**
- * returns weather the coordinates of AbstractNodes are equal.
- *
- * @param obj
- * @return
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final AbstractNode other = (AbstractNode) obj;
- if (this.xPosition != other.xPosition) {
- return false;
- }
- if (this.yPosition != other.yPosition) {
- return false;
- }
- return true;
- }
-
- /**
- * returns hash code calculated with coordinates.
- *
- * @return
- */
- @Override
- public int hashCode() {
- int hash = 3;
- hash = 17 * hash + (int)this.xPosition;
- hash = 17 * hash + (int)this.yPosition;
- return hash;
- }
-
-}
diff --git a/Newpath.pde b/Newpath.pde
new file mode 100644
index 0000000..d6163fb
--- /dev/null
+++ b/Newpath.pde
@@ -0,0 +1,21 @@
+class NewPath {
+
+ // A Path is an arraylist of points (PVector objects)
+ ArrayList> Points;
+ ArrayListLayer;
+ ArrayListpoints;
+ // A path has a radius, i.e how far is it ok for the boid to wander off
+ //float radius;
+
+ NewPath()
+ {
+ // Arbitrary radius of 30
+ //radius = 30;
+ Points = new ArrayList>();
+ //Layer=new ArrayList();
+ points=new ArrayList();
+ }
+
+ //Leave for meshinh the track for A* algorithm to be apllied.
+
+}
diff --git a/Node.java b/Node.java
deleted file mode 100644
index cc2c995..0000000
--- a/Node.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- Our Implementation of an AbstractNode
-*/
-import java.util.ArrayList;
-
-/**
- * A simple Example implementation of a Node only overriding the sethCosts
- * method; uses manhatten method.
- */
-public class Node extends AbstractNode {
-
- public static final int LEFT = 0;
- public static final int STRAIGHT = 1;
- public static final int RIGHT = 2;
- private ArrayList neighbors; // List of nodes this node is connected to
-
- public Node(float xPosition, float yPosition) {
- super(xPosition, yPosition);
- // do other init stuff
- neighbors = new ArrayList(3);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- // Neighbor Getting/Setting
- ////////////////////////////////////////////////////////////////////////////////////////////
-
- // ---------------------------------------------------------
- // Setting
- // --------------------------------------------------------
-
- public void setLeft(Node aNode) {
- neighbors.set(LEFT, aNode);
- }
-
- public void setStraight(Node aNode) {
- neighbors.set(STRAIGHT, aNode);
- }
-
- public void setRight(Node aNode) {
- neighbors.set(RIGHT, aNode);
- }
-
- public void setNext(Node aNode, int direction) {
- neighbors.set(direction, aNode);
- }
-
- public void setParent(Node aNode, int fromDirection) {
- aNode.setNext(aNode, fromDirection);
- }
-
- // ---------------------------------------------------------
- // Getting
- // --------------------------------------------------------
-
- public Node getLeft() {
- return neighbors.get(LEFT);
- }
-
- public Node getStraight() {
- return neighbors.get(STRAIGHT);
- }
-
- public Node getRight() {
- return neighbors.get(RIGHT);
- }
-
- public ArrayList getNeighbors() {
- return neighbors;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- // G cost
- ////////////////////////////////////////////////////////////////////////////////////////////
-
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode.
- *
- * @param gCosts the gCosts to set
- */
- private void setgCosts(float gCosts) {
- this.gCosts = gCosts + movementPanelty;
- }
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode given the previous AbstractNode as well as the basic cost
- * from it to this AbstractNode.
- *
- * @param previousAbstractNode
- * @param basicCost
- */
- public void setgCosts(AbstractNode previousAbstractNode, float basicCost) {
- setgCosts(previousAbstractNode.getgCosts() + basicCost);
- }
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode given the previous AbstractNode.
- *
- * It will assume BASICMOVEMENTCOST
as the cost from
- * previousAbstractNode
to itself if the movement is not diagonally,
- * otherwise it will assume DIAGONALMOVEMENTCOST
.
- * Weather or not it is diagonally is set in the Map class method which
- * finds the adjacent AbstractNodes.
- *
- * @param previousAbstractNode
- */
- public void setgCosts(AbstractNode previousAbstractNode) {
- if (diagonally) {
- setgCosts(previousAbstractNode, DIAGONALMOVEMENTCOST);
- } else {
- setgCosts(previousAbstractNode, BASICMOVEMENTCOST);
- }
- }
-
- /**
- * calculates - but does not set - g costs.
- *
- * It will assume BASICMOVEMENTCOST
as the cost from
- * previousAbstractNode
to itself if the movement is not diagonally,
- * otherwise it will assume DIAGONALMOVEMENTCOST
.
- * Weather or not it is diagonally is set in the Map class method which
- * finds the adjacent AbstractNodes.
- *
- * @param previousAbstractNode
- * @return gCosts
- */
- public float calculategCosts(AbstractNode previousAbstractNode) {
- if (diagonally) {
- return (previousAbstractNode.getgCosts()
- + DIAGONALMOVEMENTCOST + movementPanelty);
- } else {
- return (previousAbstractNode.getgCosts()
- + BASICMOVEMENTCOST + movementPanelty);
- }
- }
-
- /**
- * calculates - but does not set - g costs, adding a movementPanelty.
- *
- * @param previousAbstractNode
- * @param movementCost costs from previous AbstractNode to this AbstractNode.
- * @return gCosts
- */
- public float calculategCosts(AbstractNode previousAbstractNode, float movementCost) {
- return (previousAbstractNode.getgCosts() + movementCost + movementPanelty);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- // H cost
- ////////////////////////////////////////////////////////////////////////////////////////////
-
- /**
- * returns estimated costs to get from this AbstractNode to end AbstractNode.
- *
- * @return the hCosts
- */
- public float gethCosts() {
- return hCosts;
- }
-
- /**
- * sets hCosts.
- *
- * @param hCosts the hCosts to set
- */
- protected void sethCosts(float hCosts) {
- this.hCosts = hCosts;
- }
-
- public void sethCosts(AbstractNode endNode) {
- this.sethCosts((absolute(this.getxPosition() - endNode.getxPosition())
- + absolute(this.getyPosition() - endNode.getyPosition()))
- * BASICMOVEMENTCOST);
- }
-
- private float absolute(float a) {
- return a > 0 ? a : -a;
- }
-
-}
diff --git a/NodeFactory.java b/NodeFactory.java
deleted file mode 100644
index 99513d4..0000000
--- a/NodeFactory.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-/**
- * A Factory which creates new instances of an implementation of the
- * AbstractNode
at given coordinates.
- *
- * Must be implemented and given to Map
instance on
- * construction.
- *
- * @see AbstractNode
- * @version 1.0
- */
-public interface NodeFactory {
-
- /**
- * creates new instances of an implementation of the
- * AbstractNode
.
- * In an implementation, it should return a new node with its position
- * set to the given x and y values.
- *
- * @param x position on the x-axis
- * @param y position on the y-axis
- * @return
- */
- public AbstractNode createNode(int x, int y);
-
-}
diff --git a/PathPlanner.java b/PathPlanner.java
deleted file mode 100644
index d34dfaf..0000000
--- a/PathPlanner.java
+++ /dev/null
@@ -1,122 +0,0 @@
-import java.util.ArrayList;
-
-class PathPlanner {
- // Produces a path from a given track, startPoint, and EndPoint
- RoadBuilder trackBuilder;
- ArrayList> track;
-
- PathPlanner(Path skeleton, Node start, Node end, float straightDelta, float sideDelta, int numLanes) {
- trackBuilder = new RoadBuilder(skeleton, start, end);
- track = trackBuilder.buildRoad(straightDelta, sideDelta, numLanes);
- }
-
- /**
- * finds an allowed path from start to goal coordinates on this map.
- *
- * This method uses the A* algorithm. The hCosts value is calculated in
- * the given Node implementation.
- *
- * This method will return a LinkedList containing the start node at the
- * beginning followed by the calculated shortest allowed path ending
- * with the end node.
- *
- * If no allowed path exists, an empty list will be returned.
- *
- *
- * x/y must be bigger or equal to 0 and smaller or equal to width/hight.
- *
- * @param oldX
- * @param oldY
- * @param newX
- * @param newY
- * @return
- */
- public final List findPath(int oldX, int oldY, int newX, int newY) {
- // TODO check input
- openList = new LinkedList();
- closedList = new LinkedList();
- openList.add(nodes[oldX][oldY]); // TODO: add starting node to open list
-
- done = false;
- T current;
- while (!done) {
- current = lowestFInOpen(); // TODO: get node with lowest fCosts from openList
- closedList.add(current); // add current node to closed list
- openList.remove(current); // delete current node from open list
-
- if ((current.getxPosition() == newX)
- && (current.getyPosition() == newY)) { // found goal
- return calcPath(nodes[oldX][oldY], current); // NOTE: Looks like he back tracks from end to start t oproduce path
- }
-
- // for all adjacent nodes:
- List adjacentNodes = getAdjacent(current); // TODO:
- for (int i = 0; i < adjacentNodes.size(); i++) {
- T currentAdj = adjacentNodes.get(i);
- if (!openList.contains(currentAdj)) { // node is not in openList
- // TODO: Need to edit logic after this point
- // NOTE: May not need any of this here
- currentAdj.setPrevious(current); // set current node as previous for this node
- currentAdj.sethCosts(nodes[newX][newY]); // set h costs of this node (estimated costs to goal)
- currentAdj.setgCosts(current); // set g costs of this node (costs from start to this node)
- // NOTE: This seems okay
- openList.add(currentAdj); // add node to openList
- } else { // node is in openList
- // TODO: Implement these cost functions
- if (currentAdj.getgCosts() > currentAdj.calculategCosts(current)) { // costs from current node are cheaper than previous costs
- currentAdj.setPrevious(current); // set current node as previous for this node
- currentAdj.setgCosts(current); // set g costs of this node (costs from start to this node)
- }
- }
- }
-
- if (openList.isEmpty()) { // no path exists
- return new LinkedList(); // return empty list
- }
- }
- return null; // unreachable
- }
-
- /**
- * returns the node with the lowest fCosts.
- *
- * @return
- */
- private T lowestFInOpen(LinkedList openList) {
- // TODO currently, this is done by going through the whole openList!
- T cheapest = openList.get(0);
- for (int i = 0; i < openList.size(); i++) {
- if (openList.get(i).getfCosts() < cheapest.getfCosts()) {
- cheapest = openList.get(i);
- }
- }
- return cheapest;
- }
-
- /**
- * calculates the found path between two points according to
- * their given previousNode
field.
- *
- * @param start
- * @param goal
- * @return
- */
- private List calcPath(T start, T goal) {
- // TODO if invalid nodes are given (eg cannot find from
- // goal to start, this method will result in an infinite loop!)
- LinkedList path = new LinkedList();
-
- T curr = goal;
- boolean done = false;
- while (!done) {
- path.addFirst(curr);
- curr = (T) curr.getPrevious();
-
- if (curr.equals(start)) {
- done = true;
- }
- }
- return path;
- }
-
-}
diff --git a/RoadBuilder.java b/RoadBuilder.java
deleted file mode 100644
index 9fd1a97..0000000
--- a/RoadBuilder.java
+++ /dev/null
@@ -1,132 +0,0 @@
-
-import java.util.ArrayList;
-import java.lang.Math;
-
-
-public class RoadBuilder implements NodeFactory {
-
- private ArrayList skeleton;
- private Node startNode;
- private Node endNode;
-
- public RoadBuilder(Path skeleton, Node start, Node end) {
- this.skeleton = path2Nodes(skeleton);
- // Extract start & end nodes
- startNode = start;
- endNode = end;
- }
-
- public Node createNode(int x, int y) {
- return new Node(x, y);
- }
-
- public ArrayList pointInterpolation(Node node1, Node node2, float delta) {
- // Extract coordinates
- float x1 = node1.getxPosition();
- float y1 = node1.getyPosition();
- float x2 = node2.getxPosition();
- float y2 = node2.getyPosition();
- // Calculate some features of the line we're going to make
- double distance = euclideanDistance(x1, y1, x2, y2);
- // Rise/Run of slope
- float rise = y2 - y1;
- float run = x2 - x1;
- float slopeDelta = (float) (Math.sqrt( Math.pow(rise, 2) + Math.pow(run, 2) ));
- float proportion = delta/slopeDelta;
- rise = (float) (rise * Math.sqrt(proportion));
- run = (float) (run * Math.sqrt(proportion));
- // Start filling in new points along the line connecting these two points
- // Initialize loop variables
- ArrayList points = new ArrayList();
- double distanceCovered = 0;
- Node prevNode = node1;
- float newX = x1;
- float newY = y1;
- // Interpolate until we have covered the distance of the line
- while (distanceCovered < (distance-delta)) {
- newX += run;
- newY += rise;
- Node newNode = new Node(newX, newY);
- newNode.setParent(prevNode, Node.STRAIGHT);
- points.add(newNode);
- distanceCovered = euclideanDistance(x1, y1, newX, newY);
- }
- return points;
- }
-
- public ArrayList createLayer(Node centerNode, float delta, int num) {
- Node node1 = centerNode;
- Node node2 = node1.getStraight();
- // Extract coordinates
- float x1 = node1.getxPosition();
- float y1 = node1.getyPosition();
- float x2 = node1.getxPosition();
- float y2 = node1.getyPosition();
- // Rise/Run of slope (negative reciprical)
- // Perpendicular slope
- // https://www.mathsisfun.com/algebra/line-parallel-perpendicular.html
- float rise = -1 * (x2 - x1); // NOTE: using X (because reciprical)
- float run = y2 - y1;
- float slopeDelta = (float) (Math.sqrt( Math.pow(rise, 2) + Math.pow(run, 2) ));
- float proportion = delta/slopeDelta;
- rise = (float) (rise * Math.sqrt(proportion));
- run = (float) (run * Math.sqrt(proportion));
- // Start creating layer
- ArrayList points = new ArrayList();
- points.add(centerNode);
- // new point coordinates
- float currXleft = x1;
- float currYleft = y1;
- float currXright = x1;
- float currYright = y1;
- for (int i=1; i <= num; i++) {
- // Left side
- // calculate coordinates of new Node
- currXleft += run * i;
- currYleft += rise * i;
- Node newNode = new Node(currXleft, currYleft);
- points.add(newNode);
- // Right side
- // calculate coordinates of new Node
- currXright += -run * i;
- currYright += -rise * i;
- newNode = new Node(currXright, currYright);
- points.add(newNode);
- }
- return points;
- }
-
- public ArrayList> buildRoad(float straightDelta, float sideDelta, int numLanes) {
- ArrayList> road = new ArrayList>();
- // Line Interp center path (save as a linked list)
- int pathLength = skeleton.size();
- for (int i=0; i < pathLength; i++) {
- ArrayList interpPath = pointInterpolation(skeleton.get(i),
- skeleton.get((i+1) % pathLength),
- straightDelta);
- int interpPathLength = interpPath.size();
- for (int j=0; j < interpPathLength; j++) {
- ArrayList newLayer = createLayer(interpPath.get(j), sideDelta, numLanes/2);
- road.add(newLayer);
- }
- }
- return road;
- }
-
- public ArrayList path2Nodes(Path path) {
- ArrayList points = path.points;
- int numPoints = points.size();
- ArrayList nodeList = new ArrayList();
- for (int i=0; i < numPoints; i++) {
- PVector point = points.get(i);
- Node newNode = new Node(point.x, point.y);
- nodeList.add(newNode);
- }
- return nodeList;
- }
-
- public double euclideanDistance(float x1, float y1, float x2, float y2) {
- double squaredSum = Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2);
- return Math.sqrt(squaredSum);
- }
-}
diff --git a/Path.pde b/path.pde
similarity index 94%
rename from Path.pde
rename to path.pde
index f04986f..362f859 100644
--- a/Path.pde
+++ b/path.pde
@@ -1,9 +1,9 @@
class Path {
// A Path is an arraylist of points (PVector objects)
- public ArrayList points;
+ ArrayList points;
// A path has a radius, i.e how far is it ok for the boid to wander off
- public float radius;
+ float radius;
Path() {
// Arbitrary radius of 30
diff --git a/pathfinding/AbstractNode.java b/pathfinding/AbstractNode.java
deleted file mode 100644
index 0359fea..0000000
--- a/pathfinding/AbstractNode.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-package pathfinding;
-
-/**
- * This class represents an AbstractNode. It has all the appropriate fields as well
- * as getter and setter to be used by the A* algorithm.
- *
- *
- * An AbstractNode
has x- and y-coordinates and can be walkable or not.
- * A previous AbstractNode may be set, as well as the
- * fCosts
, gCosts
and hCosts
.
- *
- *
- * fCosts
: gCosts
+ hCosts
- *
- * gCosts
: calculated costs from start AbstractNode to this AbstractNode
- *
- * hCosts
: estimated costs to get from this AbstractNode to end AbstractNode
- *
- *
- * A subclass has to override the heuristic function
- *
- * sethCosts(AbstractNode endAbstractNode)
- *
- * @see ExampleNode#sethCosts(AbstractNode endNode) example Implementation using manhatten method
- *
- *
- * @version 1.0
- */
-public abstract class AbstractNode {
-
- /** costs to move sideways from one square to another. */
- protected static final float BASICMOVEMENTCOST = 10;
- /** costs to move diagonally from one square to another. */
- protected static final float DIAGONALMOVEMENTCOST = 14;
-
- protected float xPosition;
- protected float yPosition;
- protected boolean walkable;
-
- // for pathfinding:
-
- /** the previous AbstractNode of this one on the currently calculated path. */
- protected AbstractNode previous;
-
- /** weather or not the move from previous to this AbstractNode is diagonally. */
- protected boolean diagonally;
-
- /** optional extra penalty. */
- protected float movementPanelty;
-
- //private float fCosts; // g + h costs
-
- /** calculated costs from start AbstractNode to this AbstractNode. */
- protected float gCosts;
-
- /** estimated costs to get from this AbstractNode to end AbstractNode. */
- protected float hCosts;
-
- /**
- * constructs a walkable AbstractNode with given coordinates.
- *
- * @param xPosition
- * @param yPosition
- */
- public AbstractNode(float xPosition, float yPosition) {
- this.xPosition = xPosition;
- this.yPosition = yPosition;
- this.walkable = true;
- this.movementPanelty = 0;
- }
-
- /**
- * returns weather or not the move from the previousAbstractNode
was
- * diagonally. If it is not diagonal, it is sideways.
- *
- * @return
- */
- public boolean isDiagonaly() {
- return diagonally;
- }
-
- /**
- * sets weather or not the move from the previousAbstractNode
was
- * diagonally. If it is not diagonal, it is sideways.
- *
- * @param isDiagonaly
- */
- public void setIsDiagonaly(boolean isDiagonaly) {
- this.diagonally = isDiagonaly;
- }
-
- /**
- * sets x and y coordinates.
- *
- * @param x
- * @param y
- */
- public void setCoordinates(float x, float y) {
- this.xPosition = x;
- this.yPosition = y;
- }
-
- /**
- * @return the xPosition
- */
- public float getxPosition() {
- return xPosition;
- }
-
- /**
- * @return the yPosition
- */
- public float getyPosition() {
- return yPosition;
- }
-
- /**
- * @return the walkable
- */
- public boolean isWalkable() {
- return walkable;
- }
-
- /**
- * @param walkable the walkable to set
- */
- public void setWalkable(boolean walkable) {
- this.walkable = walkable;
- }
-
- /**
- * returns the node set as previous node on the current path.
- *
- * @return the previous
- */
- public AbstractNode getPrevious() {
- return previous;
- }
-
- /**
- * @param previous the previous to set
- */
- public void setPrevious(AbstractNode previous) {
- this.previous = previous;
- }
-
- /**
- * sets a general penalty for the movement on this node.
- *
- * @param movementPanelty the movementPanelty to set
- */
- public void setMovementPanelty(float movementPanelty) {
- this.movementPanelty = movementPanelty;
- }
-
- /**
- * returns gCosts
+ hCosts
.
- *
- *
- *
- * @return the fCosts
- */
- public float getfCosts() {
- return gCosts + hCosts;
- }
-
- /**
- * returns the calculated costs from start AbstractNode to this AbstractNode.
- *
- * @return the gCosts
- */
- public float getgCosts() {
- return gCosts;
- }
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode.
- *
- * @param gCosts the gCosts to set
- */
- private void setgCosts(float gCosts) {
- this.gCosts = gCosts + movementPanelty;
- }
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode given the previous AbstractNode as well as the basic cost
- * from it to this AbstractNode.
- *
- * @param previousAbstractNode
- * @param basicCost
- */
- public void setgCosts(AbstractNode previousAbstractNode, float basicCost) {
- setgCosts(previousAbstractNode.getgCosts() + basicCost);
- }
-
- /**
- * sets gCosts to gCosts
plus movementPanelty
- * for this AbstractNode given the previous AbstractNode.
- *
- * It will assume BASICMOVEMENTCOST
as the cost from
- * previousAbstractNode
to itself if the movement is not diagonally,
- * otherwise it will assume DIAGONALMOVEMENTCOST
.
- * Weather or not it is diagonally is set in the Map class method which
- * finds the adjacent AbstractNodes.
- *
- * @param previousAbstractNode
- */
- public void setgCosts(AbstractNode previousAbstractNode) {
- if (diagonally) {
- setgCosts(previousAbstractNode, DIAGONALMOVEMENTCOST);
- } else {
- setgCosts(previousAbstractNode, BASICMOVEMENTCOST);
- }
- }
-
- /**
- * calculates - but does not set - g costs.
- *
- * It will assume BASICMOVEMENTCOST
as the cost from
- * previousAbstractNode
to itself if the movement is not diagonally,
- * otherwise it will assume DIAGONALMOVEMENTCOST
.
- * Weather or not it is diagonally is set in the Map class method which
- * finds the adjacent AbstractNodes.
- *
- * @param previousAbstractNode
- * @return gCosts
- */
- public float calculategCosts(AbstractNode previousAbstractNode) {
- if (diagonally) {
- return (previousAbstractNode.getgCosts()
- + DIAGONALMOVEMENTCOST + movementPanelty);
- } else {
- return (previousAbstractNode.getgCosts()
- + BASICMOVEMENTCOST + movementPanelty);
- }
- }
-
- /**
- * calculates - but does not set - g costs, adding a movementPanelty.
- *
- * @param previousAbstractNode
- * @param movementCost costs from previous AbstractNode to this AbstractNode.
- * @return gCosts
- */
- public float calculategCosts(AbstractNode previousAbstractNode, float movementCost) {
- return (previousAbstractNode.getgCosts() + movementCost + movementPanelty);
- }
-
- /**
- * returns estimated costs to get from this AbstractNode to end AbstractNode.
- *
- * @return the hCosts
- */
- public float gethCosts() {
- return hCosts;
- }
-
- /**
- * sets hCosts.
- *
- * @param hCosts the hCosts to set
- */
- protected void sethCosts(float hCosts) {
- this.hCosts = hCosts;
- }
-
- /**
- * calculates hCosts for this AbstractNode to a given end AbstractNode.
- * Uses Manhatten method.
- *
- * @param endAbstractNode
- */
- public abstract void sethCosts(AbstractNode endAbstractNode);
-
-
- /*
- * @return the movementPanelty
- */
- private float getMovementPanelty() {
- return movementPanelty;
- }
-
- /**
- * returns a String containing the coordinates, as well as h, f and g
- * costs.
- *
- * @return
- */
- @Override
- public String toString() {
- return "(" + getxPosition() + ", " + getyPosition() + "): h: "
- + gethCosts() + " g: " + getgCosts() + " f: " + getfCosts();
- }
-
- /**
- * returns weather the coordinates of AbstractNodes are equal.
- *
- * @param obj
- * @return
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final AbstractNode other = (AbstractNode) obj;
- if (this.xPosition != other.xPosition) {
- return false;
- }
- if (this.yPosition != other.yPosition) {
- return false;
- }
- return true;
- }
-
- /**
- * returns hash code calculated with coordinates.
- *
- * @return
- */
- @Override
- public int hashCode() {
- int hash = 3;
- hash = 17 * hash + (int)this.xPosition;
- hash = 17 * hash + (int)this.yPosition;
- return hash;
- }
-
-}
diff --git a/pathfinding/ExampleFactory.java b/pathfinding/ExampleFactory.java
deleted file mode 100644
index 88edfdc..0000000
--- a/pathfinding/ExampleFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-package pathfinding;
-
-/**
- * A simple Factory for example nodes.
- */
-public class ExampleFactory implements NodeFactory {
-
- @Override
- public AbstractNode createNode(int x, int y) {
- return new ExampleNode(x, y);
- }
-
-}
diff --git a/pathfinding/ExampleNode.java b/pathfinding/ExampleNode.java
deleted file mode 100644
index 766eafb..0000000
--- a/pathfinding/ExampleNode.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-package pathfinding;
-
-/**
- * A simple Example implementation of a Node only overriding the sethCosts
- * method; uses manhatten method.
- */
-public class ExampleNode extends AbstractNode {
-
- public ExampleNode(int xPosition, int yPosition) {
- super(xPosition, yPosition);
- // do other init stuff
- }
-
- public void sethCosts(AbstractNode endNode) {
- // this.sethCosts((absolute(this.getxPosition() - endNode.getxPosition())
- // + absolute(this.getyPosition() - endNode.getyPosition()))
- // * BASICMOVEMENTCOST);
- }
-
- private int absolute(int a) {
- return a > 0 ? a : -a;
- }
-
-}
diff --git a/pathfinding/ExampleUsage.java b/pathfinding/ExampleUsage.java
deleted file mode 100644
index 55a1674..0000000
--- a/pathfinding/ExampleUsage.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-package pathfinding;
-
-import java.util.List;
-
-/**
- * A simple example for the usage of this package.
- *
- * @see ExampleFactory
- * @see ExampleNode
- */
-public class ExampleUsage {
-
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) {
- Map myMap = new Map(50, 50, new ExampleFactory());
- List path = myMap.findPath(0, 0, 40, 40);
-
- for (int i = 0; i < path.size(); i++) {
- System.out.print("(" + path.get(i).getxPosition() + ", " + path.get(i).getyPosition() + ") -> ");
- }
- }
-
-
-}
diff --git a/pathfinding/LICENSE b/pathfinding/LICENSE
deleted file mode 100644
index 94a9ed0..0000000
--- a/pathfinding/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- Copyright (C)
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-.
diff --git a/pathfinding/Map.java b/pathfinding/Map.java
deleted file mode 100644
index 7228188..0000000
--- a/pathfinding/Map.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-/*
- * // TODO
- * possible optimizations:
- * - calculate f as soon as g or h are set, so it will not have to be
- * calculated each time it is retrieved
- * - store nodes in openList sorted by their f value.
- */
-
-package pathfinding;
-
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * This class represents a simple map.
- *
- * It's width as well as hight can be set up on construction.
- * The map can represent nodes that are walkable or not, it can be printed
- * to sto, and it can calculate the shortest path between two nodes avoiding
- * walkable nodes.
- *
- *
- * Usage of this package:
- * Create a node class which extends AbstractNode and implements the sethCosts
- * method.
- * Create a NodeFactory that implements the NodeFactory interface.
- * Create Map instance with those created classes.
- * @see ExampleUsage ExampleUsage
- *
- *
- * @see AbstractNode
- * @see NodeFactory
- * @version 1.0
- * @param
- */
-public class Map {
-
- /** weather or not it is possible to walk diagonally on the map in general. */
- protected static boolean CANMOVEDIAGONALY = true;
-
- /** holds nodes. first dim represents x-, second y-axis. */
- private T[][] nodes;
-
- /** width + 1 is size of first dimension of nodes. */
- protected int width;
- /** higth + 1 is size of second dimension of nodes. */
- protected int higth;
-
- /** a Factory to create instances of specified nodes. */
- private NodeFactory nodeFactory;
-
- /**
- * constructs a squared map with given width and hight.
- *
- * The nodes will be instanciated througth the given nodeFactory.
- *
- * @param width
- * @param higth
- * @param nodeFactory
- */
- public Map(int width, int higth, NodeFactory nodeFactory) {
- // TODO check parameters. width and higth should be > 0.
- // TODO: Find the length of the track as the height
- this.nodeFactory = nodeFactory;
- nodes = (T[][]) new AbstractNode[width][higth];
- this.width = width - 1;
- this.higth = higth - 1;
- initEmptyNodes();
- }
-
- /**
- * initializes all nodes. Their coordinates will be set correctly.
- TODO: Edit this part
- */
- private void initEmptyNodes() {
- for (int i = 0; i <= width; i++) {
- for (int j = 0; j <= higth; j++) {
- nodes[i][j] = (T) nodeFactory.createNode(i, j);
- }
- }
- }
-
- /**
- * sets nodes walkable field at given coordinates to given value.
- *
- * x/y must be bigger or equal to 0 and smaller or equal to width/hight.
- *
- * @param x
- * @param y
- * @param bool
- */
- public void setWalkable(int x, int y, boolean bool) {
- // TODO check parameter.
- nodes[x][y].setWalkable(bool);
- }
-
- /**
- * returns node at given coordinates.
- *
- * x/y must be bigger or equal to 0 and smaller or equal to width/hight.
- *
- * @param x
- * @param y
- * @return node
- */
- public final T getNode(int x, int y) {
- // TODO check parameter.
- return nodes[x][y];
- }
-
- /**
- * prints map to sto. Feel free to override this method.
- *
- * a player will be represented as "o", an unwakable terrain as "#".
- * Movement penalty will not be displayed.
- */
- public void drawMap() {
- for (int i = 0; i <= width; i++) {
- print(" _"); // boarder of map
- }
- print("\n");
-
- for (int j = higth; j >= 0; j--) {
- print("|"); // boarder of map
- for (int i = 0; i <= width; i++) {
- if (nodes[i][j].isWalkable()) {
- print(" ");
- } else {
- print(" #"); // draw unwakable
- }
- }
- print("|\n"); // boarder of map
- }
-
- for (int i = 0; i <= width; i++) {
- print(" _"); // boarder of map
- }
- }
-
- /**
- * prints something to sto.
- */
- private void print(String s) {
- System.out.print(s);
- }
-
-
- /* Variables and methodes for path finding */
-
-
- // variables needed for path finding
-
- /** list containing nodes not visited but adjacent to visited nodes. */
- private List openList;
- /** list containing nodes already visited/taken care of. */
- private List closedList;
- /** done finding path? */
- private boolean done = false;
-
- /**
- * finds an allowed path from start to goal coordinates on this map.
- *
- * This method uses the A* algorithm. The hCosts value is calculated in
- * the given Node implementation.
- *
- * This method will return a LinkedList containing the start node at the
- * beginning followed by the calculated shortest allowed path ending
- * with the end node.
- *
- * If no allowed path exists, an empty list will be returned.
- *
- *
- * x/y must be bigger or equal to 0 and smaller or equal to width/hight.
- *
- * @param oldX
- * @param oldY
- * @param newX
- * @param newY
- * @return
- */
- public final List findPath(int oldX, int oldY, int newX, int newY) {
- // TODO check input
- openList = new LinkedList();
- closedList = new LinkedList();
- openList.add(nodes[oldX][oldY]); // TODO: add starting node to open list
-
- done = false;
- T current;
- while (!done) {
- current = lowestFInOpen(); // TODO: get node with lowest fCosts from openList
- closedList.add(current); // add current node to closed list
- openList.remove(current); // delete current node from open list
-
- if ((current.getxPosition() == newX)
- && (current.getyPosition() == newY)) { // found goal
- return calcPath(nodes[oldX][oldY], current); // NOTE: Looks like he back tracks from end to start t oproduce path
- }
-
- // for all adjacent nodes:
- List adjacentNodes = getAdjacent(current); // TODO:
- for (int i = 0; i < adjacentNodes.size(); i++) {
- T currentAdj = adjacentNodes.get(i);
- if (!openList.contains(currentAdj)) { // node is not in openList
- // TODO: Need to edit logic after this point
- // NOTE: May not need any of this here
- currentAdj.setPrevious(current); // set current node as previous for this node
- currentAdj.sethCosts(nodes[newX][newY]); // set h costs of this node (estimated costs to goal)
- currentAdj.setgCosts(current); // set g costs of this node (costs from start to this node)
- // NOTE: This seems okay
- openList.add(currentAdj); // add node to openList
- } else { // node is in openList
- // TODO: Implement these cost functions
- if (currentAdj.getgCosts() > currentAdj.calculategCosts(current)) { // costs from current node are cheaper than previous costs
- currentAdj.setPrevious(current); // set current node as previous for this node
- currentAdj.setgCosts(current); // set g costs of this node (costs from start to this node)
- }
- }
- }
-
- if (openList.isEmpty()) { // no path exists
- return new LinkedList(); // return empty list
- }
- }
- return null; // unreachable
- }
-
- /**
- * calculates the found path between two points according to
- * their given previousNode
field.
- *
- * @param start
- * @param goal
- * @return
- */
- private List calcPath(T start, T goal) {
- // TODO if invalid nodes are given (eg cannot find from
- // goal to start, this method will result in an infinite loop!)
- LinkedList path = new LinkedList();
-
- T curr = goal;
- boolean done = false;
- while (!done) {
- path.addFirst(curr);
- curr = (T) curr.getPrevious();
-
- if (curr.equals(start)) {
- done = true;
- }
- }
- return path;
- }
-
- /**
- * returns the node with the lowest fCosts.
- *
- * @return
- */
- private T lowestFInOpen() {
- // TODO currently, this is done by going through the whole openList!
- T cheapest = openList.get(0);
- for (int i = 0; i < openList.size(); i++) {
- if (openList.get(i).getfCosts() < cheapest.getfCosts()) {
- cheapest = openList.get(i);
- }
- }
- return cheapest;
- }
-
- /**
- * returns a LinkedList with nodes adjacent to the given node.
- * if those exist, are walkable and are not already in the closedList!
- */
- private List getAdjacent(T node) {
- // TODO make loop
- int x = (int)node.getxPosition();
- int y = (int)node.getyPosition();
- List adj = new LinkedList();
-
- T temp;
- if (x > 0) {
- temp = this.getNode((x - 1), y);
- if (temp.isWalkable() && !closedList.contains(temp)) {
- temp.setIsDiagonaly(false);
- adj.add(temp);
- }
- }
-
- if (x < width) {
- temp = this.getNode((x + 1), y);
- if (temp.isWalkable() && !closedList.contains(temp)) {
- temp.setIsDiagonaly(false);
- adj.add(temp);
- }
- }
-
- if (y > 0) {
- temp = this.getNode(x, (y - 1));
- if (temp.isWalkable() && !closedList.contains(temp)) {
- temp.setIsDiagonaly(false);
- adj.add(temp);
- }
- }
-
- if (y < higth) {
- temp = this.getNode(x, (y + 1));
- if (temp.isWalkable() && !closedList.contains(temp)) {
- temp.setIsDiagonaly(false);
- adj.add(temp);
- }
- }
-
-
- // add nodes that are diagonaly adjacent too:
- if (CANMOVEDIAGONALY) {
- if (x < width && y < higth) {
- temp = this.getNode((x + 1), (y + 1));
- if (temp.isWalkable() && !closedList.contains(temp)) {
- temp.setIsDiagonaly(true);
- adj.add(temp);
- }
- }
-
- if (x > 0 && y > 0) {
- temp = this.getNode((x - 1), (y - 1));
- if (temp.isWalkable() && !closedList.contains(temp)) {
- temp.setIsDiagonaly(true);
- adj.add(temp);
- }
- }
-
- if (x > 0 && y < higth) {
- temp = this.getNode((x - 1), (y + 1));
- if (temp.isWalkable() && !closedList.contains(temp)) {
- temp.setIsDiagonaly(true);
- adj.add(temp);
- }
- }
-
- if (x < width && y > 0) {
- temp = this.getNode((x + 1), (y - 1));
- if (temp.isWalkable() && !closedList.contains(temp)) {
- temp.setIsDiagonaly(true);
- adj.add(temp);
- }
- }
- }
- return adj;
- }
-
-}
diff --git a/pathfinding/NodeFactory.java b/pathfinding/NodeFactory.java
deleted file mode 100644
index a58c58c..0000000
--- a/pathfinding/NodeFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-package pathfinding;
-
-/**
- * A Factory which creates new instances of an implementation of the
- * AbstractNode
at given coordinates.
- *
- * Must be implemented and given to Map
instance on
- * construction.
- *
- * @see AbstractNode
- * @version 1.0
- */
-public interface NodeFactory {
-
- /**
- * creates new instances of an implementation of the
- * AbstractNode
.
- * In an implementation, it should return a new node with its position
- * set to the given x and y values.
- *
- * @param x position on the x-axis
- * @param y position on the y-axis
- * @return
- */
- public AbstractNode createNode(int x, int y);
-
-}
diff --git a/pathfinding/package-info.java b/pathfinding/package-info.java
deleted file mode 100644
index b0669ed..0000000
--- a/pathfinding/package-info.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- Copyright (C) 2012 http://software-talk.org/ (developer@software-talk.org)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-/**
- * This package may be used for its A* pathfinding algorithm.
- * Extend the AbstractNode class as you need, but also implement the gethCosts
- * method with a heuristic.
- * The Map class may be extended as well.
- */
-package pathfinding;
diff --git a/pathplanner.pde b/pathplanner.pde
new file mode 100644
index 0000000..a6642a4
--- /dev/null
+++ b/pathplanner.pde
@@ -0,0 +1,27 @@
+class PathPlanner {
+ // Produces a path from a given track, startPoint, and EndPoint
+
+ Path track = null; // Path of the track it's given
+ Path path = null; // Path it produces
+ PVector startPoint = null; // Start point on the path
+ PVector endPoint = null; // Destination point
+
+ PathPlanner(Path atrack, PVector start, PVector destination) {
+ track = atrack;
+ startPoint = start;
+ endPoint = destination;
+ path = new Path();
+ }
+
+ void discritizeTrack() {
+ // Make the track a little more refined, to allow for more careful decisions
+
+ }
+
+ Path pathFinder() {
+ // Returns a Path through the track
+
+ return null;
+ }
+
+}
diff --git a/simulation.pde b/simulation.pde
index f8e3f3a..c3b044a 100644
--- a/simulation.pde
+++ b/simulation.pde
@@ -31,9 +31,10 @@ void setup()
// Call a function to generate new Path object
newPath();
- // Each vehicle has different maxspeed and maxforce for demo purposes
- car1 = new Vehicle(new PVector(0, height/2), 1, 0.04);
- car2 = new Vehicle(new PVector(0, height/2), 1, 2);
+ // Each vehicle has sanme maxspeed and different maxforce for different peroformance.
+ //You could set different parameters to check different perfomance.
+ car1 = new Vehicle(new PVector(0, height/2-400), 1, 0.04);
+ car2 = new Vehicle(new PVector(0, height/2-400), 1, 2);
}
//////////////////////////////////////////////////////////////////
@@ -65,18 +66,6 @@ void draw()
}
// Here define the element of the track
-/*void newPath()
-{
- // A path is a series of connected points
- // A more sophisticated path might be a curve, if you want to have a try.
- path = new Path();
- path.addPoint(100, height/2);
- path.addPoint(100,height/2+200);
- path.addPoint(300,height/2+200);
- path.addPoint(300,height/2);
- // path.addPoint(200, height/2+5);
-}*/
-
void newPath() {
// A path is a series of connected points
diff --git a/Vehicle.pde b/vehicle.pde
similarity index 91%
rename from Vehicle.pde
rename to vehicle.pde
index 2b33902..02ce03e 100644
--- a/Vehicle.pde
+++ b/vehicle.pde
@@ -1,353 +1,341 @@
-class Vehicle
-{
-
- // All the usual parameters;
- PVector position;
- PVector velocity;
- PVector acceleration;
- float r;
- float maxforce; // Maximum steering force. Here I assume the weight of the car is 1. So it is actually the acceleration.
- float maxspeed; // Maximum speed
-
- // Constructor initialize all values
- Vehicle(PVector l, float ms, float mf)
- {
- position = l.get();
- r = 4.0;
- maxspeed = ms;
- maxforce = mf;
- acceleration = new PVector(0, 0);
- velocity = new PVector(maxspeed, 0);
- }
-
- // Main run function
- void run()
- {
- update();
- display();
- }
-
-
- //Here is the main part of the pure pursuit algorithm
- int i=0;
- int ii=0;
- PVector a;
- PVector b;
- float angle;
- PVector aa;
- PVector bb;
- PVector cc;
-
- // PVector a = p.points.get(0);
- //PVector b = p.end;
- void follow(Path p)
-
- {
- if(i==0)
- {
- a = p.points.get(0);
- b = p.points.get(1);
- }
-
- //print(i);
- if(i==p.points.size()-1)
- {
-
- aa=a;
- bb=b;
- a = p.points.get(i);
- b = p.points.get(0);
- cc=b;
- angle= PVector.angleBetween(PVector.sub( bb,aa) , PVector.sub(cc,bb) );
- angle=angle*180/PI;
- print(angle);
- print("\n");
-
- }
- else
- {
- aa=a;
- bb=b;
- a = p.points.get(i);
- b = p.points.get(i+1);
- cc=b;
- angle= PVector.angleBetween(PVector.sub(bb,aa) , PVector.sub(cc,bb) );
- angle=angle*180/PI;
- print(angle);
- print("\n");
- if(ii!=0 )
- {
- if(i<=p.points.size()-3)
- {
- aa=p.points.get(i);
- bb=p.points.get(i+1);
- cc=p.points.get(i+2);
- angle= PVector.angleBetween(PVector.sub(bb,aa) , PVector.sub(cc,bb) );
- angle=angle*180/PI;
- print(angle);
- print("\n");
- }
- //angle=200;
- if (i==p.points.size()-2)
- {
- aa=p.points.get(i);
- bb=p.points.get(i+1);
- cc=p.points.get(i+2-p.points.size());
- angle= PVector.angleBetween(PVector.sub(bb,aa) , PVector.sub(cc,bb) );
- angle=angle*180/PI;
- print(angle);
- print("\n");
- }
-
- if (i==p.points.size()-1)
- {
- aa=p.points.get(i);
- bb=p.points.get(i+1-p.points.size());
- cc=p.points.get(i+2-p.points.size());
- angle= PVector.angleBetween(PVector.sub(bb,aa) , PVector.sub(cc,bb) );
- angle=angle*180/PI;
- print(angle);
- print("\n");
- }
- }
-
-
-
- }
- //PVector a = p.points.get(i);
- //PVector b = p.points.get(i+1);
- // Predict position 50 (arbitrary choice) frames ahead
- PVector predict = velocity.get();
- predict.normalize();
- predict.mult(50);
- PVector predictpos = PVector.add(position, predict);
-
-
- // Get the normal point to that line
- PVector normalPoint = getNormalPoint(predictpos, a, b);
-
- // Find target point a little further ahead of normal
- PVector dir = PVector.sub(b, a);
- dir.normalize();
- dir.mult(1); // This could be based on velocity instead of just an arbitrary 10 pixels
- PVector target = PVector.add(normalPoint, dir);
-
- // How far away are we from the path?
- float distance = PVector.dist(predictpos, normalPoint);
-
-
-
- // The commented one is to show that, keep the car is in the track instead of staying in the middle of the line.
- //if (distance > p.radius)
- if (distance > 0)
- {
- seek(target);
- //print(target);
- //print(b);
- // print('\n');
- // print();
- }
- // Test if the target position of car is close to the end part of the line.
- if(angle> 90)
- {
- //print("Fuck");
- if(abs(target.x-b.x)<1 && abs(target.y-b.y)<1)
- //if(abs(position.x-b.x)<10 && abs(position.y-b.y)<10)
- {
- i++;
- //float aa= PVector.angleBetween(PVector.sub( p.points.get(i),p.points.get(i-1)) , PVector.sub(p.points.get(i+1),p.points.get(i)) );
- //print(aa*180/PI);
- print("/n");
- /*if(i==p.points.size()-1)
- {
- //i--;
- i=0;
- }*/
- //print(i);
- /*if(abs(target.x-p.points.get(0).x)<5 && abs(target.y-p.points.get(0).y)<5)
- {
- i=0;
- print(i);
- }*/
- if(b==p.points.get(0))
- {
- i=0;
- }
-
- if(ii==0)
-
- {
- if(abs(target.x - p.points.get(2).x )<5 && abs(target.y - p.points.get(2).y )<500)
- {
- position.x=position.x-100;
- position.y=position.y-300;
- i--;
- ii++;
- print("The push");
- print(i);
- }
- }
-
- }
- }
-
- else
- {
- if(abs(position.x-b.x)<5 && abs(position.y-b.y)<5)
- //if(abs(position.x-b.x)<10 && abs(position.y-b.y)<10)
- {
- i++;
- //float aa= PVector.angleBetween(PVector.sub( p.points.get(i),p.points.get(i-1)) , PVector.sub(p.points.get(i+1),p.points.get(i)) );
- //print(aa*180/PI);
- print("/n");
- /*if(i==p.points.size()-1)
- {
- //i--;
- i=0;
- }*/
- //print(i);
- /*if(abs(target.x-p.points.get(0).x)<5 && abs(target.y-p.points.get(0).y)<5)
- {
- i=0;
- print(i);
- }*/
-
- if(b==p.points.get(0))
- {
- i=0;
- }
- if(ii==0)
-
- {
- if(abs(target.x - p.points.get(2).x )<5 && abs(target.y - p.points.get(2).y )<500)
- {
- position.x=position.x-100;
- position.y=position.y-300;
- i--;
- ii++;
- print("The push");
- print(i);
- }
- }
-
- }
- }
-
-
- //Test if the car back to the original position. So that we need to set the we follow the track at the the beginning of the path
- /*if(abs(position.x-p.points.get(0).x)<20 && abs(position.y-p.points.get(0).y)<20)
- {
- i=0;
- print(i);
- }*/
-
- // Draw the debugging stuff
- if (debug)
- {
- fill(0);
- stroke(0);
- line(position.x, position.y, predictpos.x, predictpos.y);
- ellipse(predictpos.x, predictpos.y, 4, 4);
-
- // Draw normal position
- fill(0);
- stroke(0);
- line(predictpos.x, predictpos.y, normalPoint.x, normalPoint.y);
- ellipse(normalPoint.x, normalPoint.y, 4, 4);
- stroke(0);
- if (distance > p.radius) fill(255, 0, 0);
- noStroke();
- ellipse(target.x+dir.x, target.y+dir.y, 8, 8);
- }
- }
-
-
- // A function to get the normal point from a point (p) to a line segment (a-b)
- // This function could be optimized to make fewer new Vector objects
- PVector getNormalPoint(PVector p, PVector a, PVector b)
- {
- // Vector from a to p
- PVector ap = PVector.sub(p, a);
- // Vector from a to b
- PVector ab = PVector.sub(b, a);
- ab.normalize(); // Normalize the line
- // Project vector "diff" onto line by using the dot product
- ab.mult(ap.dot(ab));
- PVector normalPoint = PVector.add(a, ab);
- return normalPoint;
- }
-
-
- // Method to update position
- void update()
- {
- // Update velocity
- velocity.add(acceleration);
- // Limit speed
- velocity.limit(maxspeed);
- position.add(velocity);
- // Reset accelertion to 0 each cycle
- acceleration.mult(0);
- }
-
- void applyForce(PVector force)
- {
- // We could add mass here if we want A = F / M, but I assume the weight is 1, so it is fine.
- acceleration.add(force);
- }
-
-
- // A method that calculates and applies a steering force towards a target
- // STEER = DESIRED MINUS VELOCITY
- void seek(PVector target)
- {
- PVector desired = PVector.sub(target, position); // A vector pointing from the position to the target
-
- // If the magnitude of desired equals 0, skip out of here
- // (We could optimize this to check if x and y are 0 to avoid mag() square root)
- if (desired.mag() == 0) return;
-
- // Normalize desired and scale to maximum speed
- desired.normalize();
- desired.mult(maxspeed);
- // Steering = Desired minus Velocity
- PVector steer = PVector.sub(desired, velocity);
- steer.limit(maxforce); // Limit to maximum steering force
-
- applyForce(steer);
- }
-
- void display()
- {
- // Draw a triangle rotated in the direction of velocity
- float theta = velocity.heading2D() + radians(90);
- fill(175);
- stroke(0);
- pushMatrix();
- translate(position.x, position.y);
- rotate(theta);
- beginShape(PConstants.TRIANGLES);
- vertex(0, -r*2);
- vertex(-r, r*2);
- vertex(r, r*2);
- endShape();
- popMatrix();
- }
-
- // Wraparound
- /* void borders(Path p)
- {
- if (position.x > p.getEnd().x + r)
- {
- position.x = p.getStart().x - r;
- position.y = p.getStart().y + (position.y-p.getEnd().y);
- }
- }*/
- /*void borders() {
- if (position.x < -r) position.x = width+r;
- //if (position.y < -r) position.y = height+r;
- if (position.x > width+r) position.x = -r;
- //if (position.y > height+r) position.y = -r;
- }*/
-
-}
+class Vehicle
+{
+
+ // All the usual parameters;
+ PVector position;
+ PVector velocity;
+ PVector acceleration;
+ float r;
+ float maxforce; // Maximum steering force. Here I assume the weight of the car is 1. So it is actually the acceleration.
+ float maxspeed; // Maximum speed
+
+ // Constructor initialize all values
+ Vehicle(PVector l, float ms, float mf)
+ {
+ position = l.get();
+ r = 4.0;
+ maxspeed = ms;
+ maxforce = mf;
+ acceleration = new PVector(0, 0);
+ velocity = new PVector(maxspeed, 0);
+ }
+
+ // Main run function
+ void run()
+ {
+ update();
+ display();
+ }
+
+
+ //Here is the main part of the pure pursuit algorithm
+ int i=0;
+ int ii=0;
+ PVector a;
+ PVector b;
+ float angle;
+ PVector aa;
+ PVector bb;
+ PVector cc;
+
+
+ void follow(Path p)
+
+ {
+ if(i==0)
+ {
+ a = p.points.get(0);
+ b = p.points.get(1);
+ }
+
+ //Depend on the next steering angle, choose a modified steer choice instead of the constant look-ahead distance.
+
+ if(i==p.points.size()-1)
+ {
+
+ aa=a;
+ bb=b;
+ a = p.points.get(i);
+ b = p.points.get(0);
+ cc=b;
+ angle= PVector.angleBetween(PVector.sub( bb,aa) , PVector.sub(cc,bb) );
+ angle=angle*180/PI;
+ print(angle);
+ print("\n");
+
+ }
+ else
+ {
+ aa=a;
+ bb=b;
+ a = p.points.get(i);
+ b = p.points.get(i+1);
+ cc=b;
+ angle= PVector.angleBetween(PVector.sub(bb,aa) , PVector.sub(cc,bb) );
+ angle=angle*180/PI;
+ print(angle);
+ print("\n");
+ if(ii!=0 )
+ {
+ if(i<=p.points.size()-3)
+ {
+ aa=p.points.get(i);
+ bb=p.points.get(i+1);
+ cc=p.points.get(i+2);
+ angle= PVector.angleBetween(PVector.sub(bb,aa) , PVector.sub(cc,bb) );
+ angle=angle*180/PI;
+ print(angle);
+ print("\n");
+ }
+
+
+ if (i==p.points.size()-2)
+ {
+ aa=p.points.get(i);
+ bb=p.points.get(i+1);
+ cc=p.points.get(i+2-p.points.size());
+ angle= PVector.angleBetween(PVector.sub(bb,aa) , PVector.sub(cc,bb) );
+ angle=angle*180/PI;
+ print(angle);
+ print("\n");
+ }
+
+ if (i==p.points.size()-1)
+ {
+ aa=p.points.get(i);
+ bb=p.points.get(i+1-p.points.size());
+ cc=p.points.get(i+2-p.points.size());
+ angle= PVector.angleBetween(PVector.sub(bb,aa) , PVector.sub(cc,bb) );
+ angle=angle*180/PI;
+ print(angle);
+ print("\n");
+ }
+ }
+
+
+
+ }
+
+ PVector predict = velocity.get();
+ predict.normalize();
+ predict.mult(50);
+ PVector predictpos = PVector.add(position, predict);
+
+
+ // Get the normal point to that line
+ PVector normalPoint = getNormalPoint(predictpos, a, b);
+
+ // Find target point a little further ahead of normal
+ PVector dir = PVector.sub(b, a);
+ dir.normalize();
+ dir.mult(1); // This could be based on velocity instead of just an arbitrary 10 pixels
+ PVector target = PVector.add(normalPoint, dir);
+
+ // How far away are we from the path?
+ float distance = PVector.dist(predictpos, normalPoint);
+
+
+
+ // The commented one is to show that, keep the car is in the track instead of staying in the middle of the line.
+ //if (distance > p.radius)
+ if (distance > 0)
+ {
+ seek(target);
+ //print(target);
+ //print(b);
+ // print('\n');
+ // print();
+ }
+ // Test if the target position of car is close to the end part of the line.
+ if(angle> 90)
+ {
+ //print("Fuck");
+ if(abs(target.x-b.x)<1 && abs(target.y-b.y)<1)
+ //if(abs(position.x-b.x)<10 && abs(position.y-b.y)<10)
+ {
+ i++;
+ //float aa= PVector.angleBetween(PVector.sub( p.points.get(i),p.points.get(i-1)) , PVector.sub(p.points.get(i+1),p.points.get(i)) );
+ //print(aa*180/PI);
+ print("/n");
+ /*if(i==p.points.size()-1)
+ {
+ //i--;
+ i=0;
+ }*/
+ //print(i);
+ /*if(abs(target.x-p.points.get(0).x)<5 && abs(target.y-p.points.get(0).y)<5)
+ {
+ i=0;
+ print(i);
+ }*/
+ if(b==p.points.get(0))
+ {
+ i=0;
+ }
+
+ if(ii==0)
+
+ {
+ if(abs(target.x - p.points.get(2).x )<5 && abs(target.y - p.points.get(2).y )<500)
+ {
+ position.x=position.x-100;
+ position.y=position.y-300;
+ i--;
+ ii++;
+ print("The push");
+ print(i);
+ }
+ }
+
+ }
+ }
+
+ else
+ {
+ if(abs(position.x-b.x)<5 && abs(position.y-b.y)<5)
+
+ {
+ i++;
+
+ print("/n");
+
+
+ if(b==p.points.get(0))
+ {
+ i=0;
+ }
+ if(ii==0)
+
+ {
+ if(abs(target.x - p.points.get(2).x )<5 && abs(target.y - p.points.get(2).y )<500)
+ {
+ position.x=position.x-100;
+ position.y=position.y-300;
+ i--;
+ ii++;
+ print("The push");
+ print(i);
+ }
+ }
+
+ }
+ }
+
+
+ //Test if the car back to the original position. So that we need to set the we follow the track at the the beginning of the path
+ /*if(abs(position.x-p.points.get(0).x)<20 && abs(position.y-p.points.get(0).y)<20)
+ {
+ i=0;
+ print(i);
+ }*/
+
+ // Draw the debugging stuff
+ if (debug)
+ {
+ fill(0);
+ stroke(0);
+ line(position.x, position.y, predictpos.x, predictpos.y);
+ ellipse(predictpos.x, predictpos.y, 4, 4);
+
+ // Draw normal position
+ fill(0);
+ stroke(0);
+ line(predictpos.x, predictpos.y, normalPoint.x, normalPoint.y);
+ ellipse(normalPoint.x, normalPoint.y, 4, 4);
+ stroke(0);
+ if (distance > p.radius) fill(255, 0, 0);
+ noStroke();
+ ellipse(target.x+dir.x, target.y+dir.y, 8, 8);
+ }
+ }
+
+
+ // A function to get the normal point from a point (p) to a line segment (a-b)
+ // This function could be optimized to make fewer new Vector objects
+ PVector getNormalPoint(PVector p, PVector a, PVector b)
+ {
+ // Vector from a to p
+ PVector ap = PVector.sub(p, a);
+ // Vector from a to b
+ PVector ab = PVector.sub(b, a);
+ ab.normalize(); // Normalize the line
+ // Project vector "diff" onto line by using the dot product
+ ab.mult(ap.dot(ab));
+ PVector normalPoint = PVector.add(a, ab);
+ return normalPoint;
+ }
+
+
+ // Method to update position
+ void update()
+ {
+ // Update velocity
+ velocity.add(acceleration);
+ // Limit speed
+ velocity.limit(maxspeed);
+ position.add(velocity);
+ // Reset accelertion to 0 each cycle
+ acceleration.mult(0);
+ }
+
+ void applyForce(PVector force)
+ {
+ // We could add mass here if we want A = F / M, but I assume the weight is 1, so it is fine.
+ acceleration.add(force);
+ }
+
+
+ // A method that calculates and applies a steering force towards a target
+ // STEER = DESIRED MINUS VELOCITY
+ void seek(PVector target)
+ {
+ PVector desired = PVector.sub(target, position); // A vector pointing from the position to the target
+
+ // If the magnitude of desired equals 0, skip out of here
+ // (We could optimize this to check if x and y are 0 to avoid mag() square root)
+ if (desired.mag() == 0) return;
+
+ // Normalize desired and scale to maximum speed
+ desired.normalize();
+ desired.mult(maxspeed);
+ // Steering = Desired minus Velocity
+ PVector steer = PVector.sub(desired, velocity);
+ steer.limit(maxforce); // Limit to maximum steering force
+
+ applyForce(steer);
+ }
+
+ void display()
+ {
+ // Draw a triangle rotated in the direction of velocity
+ float theta = velocity.heading2D() + radians(90);
+ fill(175);
+ stroke(0);
+ pushMatrix();
+ translate(position.x, position.y);
+ rotate(theta);
+ beginShape(PConstants.TRIANGLES);
+ vertex(0, -r*2);
+ vertex(-r, r*2);
+ vertex(r, r*2);
+ endShape();
+ popMatrix();
+ }
+
+ // Wraparound
+ /* void borders(Path p)
+ {
+ if (position.x > p.getEnd().x + r)
+ {
+ position.x = p.getStart().x - r;
+ position.y = p.getStart().y + (position.y-p.getEnd().y);
+ }
+ }*/
+ /*void borders() {
+ if (position.x < -r) position.x = width+r;
+ //if (position.y < -r) position.y = height+r;
+ if (position.x > width+r) position.x = -r;
+ //if (position.y > height+r) position.y = -r;
+ }*/
+
+}