fix last convex polygon
This commit is contained in:
parent
a41403e080
commit
155e804b95
151
Boid.pde
151
Boid.pde
|
@ -1,6 +1,6 @@
|
||||||
/// In this file, you will have to implement seek and waypoint-following
|
/// In this file, you will have to implement seek and waypoint-following
|
||||||
/// The relevant locations are marked with "TODO"
|
/// The relevant locations are marked with "TODO"
|
||||||
import java.util.*;
|
|
||||||
class Crumb
|
class Crumb
|
||||||
{
|
{
|
||||||
PVector position;
|
PVector position;
|
||||||
|
@ -18,61 +18,6 @@ class Crumb
|
||||||
|
|
||||||
class Boid
|
class Boid
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
Crumb[] crumbs = {};
|
|
||||||
int last_crumb;
|
|
||||||
float acceleration;
|
|
||||||
float rotational_acceleration;
|
|
||||||
KinematicMovement kinematic;
|
|
||||||
PVector target;
|
|
||||||
|
|
||||||
Boid(PVector position, float heading, float max_speed, float max_rotational_speed, float acceleration, float rotational_acceleration)
|
|
||||||
{
|
|
||||||
this.kinematic = new KinematicMovement(position, heading, max_speed, max_rotational_speed);
|
|
||||||
this.last_crumb = millis();
|
|
||||||
this.acceleration = acceleration;
|
|
||||||
this.rotational_acceleration = rotational_acceleration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float dt)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (waypoints != null) {
|
|
||||||
for (int i = 0; i<waypoints.size(); i++)
|
|
||||||
{
|
|
||||||
text(i, waypoints.get(i).x + 10, waypoints.get(i).y + 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target != null)
|
|
||||||
{
|
|
||||||
// TODO: Implement seek here
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//This makes a vector with the direction our boid needs to go to
|
|
||||||
PVector direction = PVector.sub(target, kinematic.position);
|
|
||||||
|
|
||||||
//atan2(direction.y, direction.x) will return the direction we need to go in radians
|
|
||||||
|
|
||||||
//print direction we need to go and the direction we are facing right now
|
|
||||||
//println(atan2(direction.y, direction.x) + " " + normalize_angle_left_right(kinematic.getHeading()));
|
|
||||||
|
|
||||||
float directionalThreshold = .1;
|
|
||||||
float angleToTarget = normalize_angle_left_right(atan2(direction.y, direction.x) - normalize_angle_left_right(kinematic.getHeading()));
|
|
||||||
float arrivalThreshold = 60.0;
|
|
||||||
|
|
||||||
//This just draws a circle for visual debugging purposes
|
|
||||||
circle(target.x, target.y, 3);
|
|
||||||
|
|
||||||
//prints the angle to the target
|
|
||||||
//println(angleToTarget);
|
|
||||||
|
|
||||||
//if the angle is larger than the threshold in the positive direction, rotate counterclockwise
|
|
||||||
if (angleToTarget >= .1) {
|
|
||||||
//println("positive angle");
|
|
||||||
kinematic.increaseSpeed(0.0, 2);
|
|
||||||
|
|
||||||
=======
|
|
||||||
Crumb[] crumbs = {};
|
Crumb[] crumbs = {};
|
||||||
int last_crumb;
|
int last_crumb;
|
||||||
float acceleration;
|
float acceleration;
|
||||||
|
@ -91,7 +36,6 @@ class Boid
|
||||||
this.acceleration = acceleration;
|
this.acceleration = acceleration;
|
||||||
this.rotational_acceleration = rotational_acceleration;
|
this.rotational_acceleration = rotational_acceleration;
|
||||||
}
|
}
|
||||||
>>>>>>> 3d16b646a807cb7a2384072f4c267c5888644f96
|
|
||||||
|
|
||||||
void update(float dt)
|
void update(float dt)
|
||||||
{
|
{
|
||||||
|
@ -142,39 +86,6 @@ class Boid
|
||||||
kinematic.increaseSpeed(0.0, kinematic.getRotationalVelocity());
|
kinematic.increaseSpeed(0.0, kinematic.getRotationalVelocity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Sometimes our Boid just goes and does weird things and I don't know why
|
|
||||||
|
|
||||||
//if the target is outside its arrival threshold, accelerate.
|
|
||||||
//if the target is inside its arrival threshold, accelerate backwards until the speed is 0.
|
|
||||||
if (direction.mag() > arrivalThreshold) {
|
|
||||||
//println("main if");
|
|
||||||
kinematic.increaseSpeed(.5, 0);
|
|
||||||
} else if (direction.mag() < arrivalThreshold) {
|
|
||||||
//Need more specific code here to handle arrivals correctly
|
|
||||||
|
|
||||||
if (kinematic.getSpeed() < 40 && direction.mag() > 30) {
|
|
||||||
//println("if 1");
|
|
||||||
kinematic.increaseSpeed(1, 0);
|
|
||||||
} else if (kinematic.getSpeed() < 20 && direction.mag() > 15) {
|
|
||||||
//println("if .75");
|
|
||||||
kinematic.increaseSpeed(.75, 0);
|
|
||||||
} else if (kinematic.getSpeed() < 10 && direction.mag() > 5) {
|
|
||||||
//println("if .5");
|
|
||||||
kinematic.increaseSpeed(.5, 0);
|
|
||||||
} else if (kinematic.getSpeed() < 5 && direction.mag() < 5) {
|
|
||||||
//println("if -kin");
|
|
||||||
//This should ensure that the boid's speed can be dropped to exactly 0 so we don't have stuttering
|
|
||||||
|
|
||||||
kinematic.increaseSpeed(-kinematic.getSpeed(), 0);
|
|
||||||
} else {
|
|
||||||
//println("else");
|
|
||||||
kinematic.increaseSpeed(-1, 0);
|
|
||||||
=======
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,7 +194,6 @@ class Boid
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
>>>>>>> 3d16b646a807cb7a2384072f4c267c5888644f96
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -328,64 +238,6 @@ class Boid
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
// //println("func count " + count);
|
|
||||||
// if(count > waypoints.size() - 1){
|
|
||||||
// this.target = waypoints.get(0);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// // TODO: change to follow *all* waypoints
|
|
||||||
// println("count " + count);
|
|
||||||
// this.target = waypoints.get(count);
|
|
||||||
// PVector temp = waypoints.remove(count);
|
|
||||||
// count++;
|
|
||||||
// //count--;
|
|
||||||
|
|
||||||
// follow(waypoints);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//}
|
|
||||||
void follow(ArrayList<PVector> waypoints)
|
|
||||||
{
|
|
||||||
if(waypoints.size() == 0) return;
|
|
||||||
println("vector " + waypoints);
|
|
||||||
println("reverse vector " + waypoints);
|
|
||||||
int count = 0;
|
|
||||||
PVector stop = waypoints.get(0);
|
|
||||||
this.seek(stop);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PVector temp = waypoints.remove(0);
|
|
||||||
println("temp vector " + waypoints);
|
|
||||||
//follow(waypoints);
|
|
||||||
|
|
||||||
//this.target = waypoints.get(0);
|
|
||||||
//do{
|
|
||||||
|
|
||||||
|
|
||||||
// println("in while " + count);
|
|
||||||
////this.target = waypoints.get(count);
|
|
||||||
//this.target = waypoints.get(count);
|
|
||||||
//if(PVector.sub(this.target,this.kinematic.position).mag() < 40){
|
|
||||||
// count++;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//}while(count < waypoints.size());
|
|
||||||
//count++;
|
|
||||||
//for(int i = 1; i < waypoints.size(); i++){
|
|
||||||
// println("dist " + PVector.sub(this.target,this.kinematic.position).mag());
|
|
||||||
// if(PVector.sub(this.target,this.kinematic.position).mag() < 40){
|
|
||||||
// this.seek(waypoints.get(i));
|
|
||||||
// this.target = waypoints.get(i);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
=======
|
|
||||||
// place crumbs, do not change
|
// place crumbs, do not change
|
||||||
if (LEAVE_CRUMBS && (millis() - this.last_crumb > CRUMB_INTERVAL))
|
if (LEAVE_CRUMBS && (millis() - this.last_crumb > CRUMB_INTERVAL))
|
||||||
{
|
{
|
||||||
|
@ -448,5 +300,4 @@ class Boid
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
>>>>>>> 3d16b646a807cb7a2384072f4c267c5888644f96
|
|
||||||
}
|
}
|
||||||
|
|
51
NavMesh.pde
51
NavMesh.pde
|
@ -126,7 +126,7 @@ class NavMesh
|
||||||
//}
|
//}
|
||||||
for (Node a: nodes)
|
for (Node a: nodes)
|
||||||
{
|
{
|
||||||
//this is terrible for efficiency i'm so sorry
|
|
||||||
for (Node b: nodes)
|
for (Node b: nodes)
|
||||||
{
|
{
|
||||||
if (b.equals(a)) continue;
|
if (b.equals(a)) continue;
|
||||||
|
@ -167,12 +167,11 @@ class NavMesh
|
||||||
|
|
||||||
int next_index = i+1;
|
int next_index = i+1;
|
||||||
if (next_index > node_verts.size()-1) next_index = 0;
|
if (next_index > node_verts.size()-1) next_index = 0;
|
||||||
polygon_1.add( new Wall(node_verts.get(i), node_verts.get(next_index)) );
|
polygon_1.add(new Wall(node_verts.get(i), node_verts.get(next_index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//for polygon_2
|
|
||||||
//a little bit tricker, since poly b has a disjunction between vertex indices
|
|
||||||
//the loop is thus different for constructing b
|
|
||||||
//start from index_2 and go further until you hit index A. You are guaranteed to finish the polygon once you connect A and B.
|
//start from index_2 and go further until you hit index A. You are guaranteed to finish the polygon once you connect A and B.
|
||||||
int i = index_2;
|
int i = index_2;
|
||||||
boolean completedpolygon_2 = false;
|
boolean completedpolygon_2 = false;
|
||||||
|
@ -191,30 +190,22 @@ class NavMesh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//we'll create a node to store poly a
|
|
||||||
Node nodeA = new Node(recursionDepth+"A", polygon_1);
|
Node nodeA = new Node(recursionDepth+"A", polygon_1);
|
||||||
setIndices(nodeA);
|
setIndices(nodeA);
|
||||||
nodes.add(nodeA);
|
nodes.add(nodeA);
|
||||||
|
|
||||||
//the same goes for b
|
|
||||||
Node nodeB = new Node(recursionDepth+"B", polygon_2);
|
Node nodeB = new Node(recursionDepth+"B", polygon_2);
|
||||||
setIndices(nodeB);
|
setIndices(nodeB);
|
||||||
nodes.add(nodeB);
|
nodes.add(nodeB);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//this portion is not at all necessary for the program to function but it helps when debugging
|
|
||||||
recursionDepth++;
|
recursionDepth++;
|
||||||
if (recursionDepth == maxDepth) return;
|
if (recursionDepth == maxDepth) return;
|
||||||
|
|
||||||
//polygons are added to the node list, in order of A and B
|
|
||||||
//0.[NODE 0A]
|
|
||||||
//1.[NODE 0B]
|
|
||||||
|
|
||||||
//findReflexVertex will return -1 if the shape is all good
|
|
||||||
//remove the bad nodes from the list and add in two new ones
|
|
||||||
//order in the node list has no effect on neighboursing
|
|
||||||
//the node list functions identically to a bag in that regard
|
|
||||||
if (findReflexVertex(polygon_1) != -1) {
|
if (findReflexVertex(polygon_1) != -1) {
|
||||||
nodes.remove(nodeA);
|
nodes.remove(nodeA);
|
||||||
convexDecomposition(nodeA);
|
convexDecomposition(nodeA);
|
||||||
|
@ -229,18 +220,21 @@ class NavMesh
|
||||||
int findReflexVertex(ArrayList<Wall> polygon)
|
int findReflexVertex(ArrayList<Wall> polygon)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int i = 0; i<polygon.size() - 1; i++)
|
for (int i = 0; i<polygon.size(); i++)
|
||||||
{
|
{
|
||||||
// finding the reflex angle by finding where it turns right
|
// finding the reflex angle by finding where it turns right
|
||||||
if (polygon.get(i).normal.dot(polygon.get(i + 1).direction) >= 0) {
|
int j = i + 1;
|
||||||
return i + 1;
|
// for index out of bounds
|
||||||
|
if( j >= polygon.size()) j = 0;
|
||||||
|
if (polygon.get(i).normal.dot(polygon.get(j).direction) >= 0) {
|
||||||
|
return j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//given a reflexive index, find a vertex that you can go to without intersection another wall
|
|
||||||
int joiningVertex(ArrayList<Wall> polygon, int convex_index)
|
int joiningVertex(ArrayList<Wall> polygon, int convex_index)
|
||||||
{
|
{
|
||||||
//you need the PVectors for this one
|
//you need the PVectors for this one
|
||||||
|
@ -250,10 +244,9 @@ class NavMesh
|
||||||
vertices.add(w.start);
|
vertices.add(w.start);
|
||||||
}
|
}
|
||||||
|
|
||||||
//our "bad" point
|
|
||||||
PVector pointAtIndex = vertices.get(convex_index);
|
PVector pointAtIndex = vertices.get(convex_index);
|
||||||
|
|
||||||
//we don't need to consider the vertex's neighbours since they obviously can't be connected to
|
|
||||||
int next_index = convex_index + 1;
|
int next_index = convex_index + 1;
|
||||||
if (next_index >= vertices.size()) next_index = 0;
|
if (next_index >= vertices.size()) next_index = 0;
|
||||||
|
|
||||||
|
@ -262,7 +255,7 @@ class NavMesh
|
||||||
|
|
||||||
for (int potentialConnecting = vertices.size()-1; potentialConnecting>=0; potentialConnecting--)
|
for (int potentialConnecting = vertices.size()-1; potentialConnecting>=0; potentialConnecting--)
|
||||||
{
|
{
|
||||||
//skip neighbours and the bad point
|
|
||||||
if (potentialConnecting == next_index || potentialConnecting == convex_index || potentialConnecting == lastIndex) continue;
|
if (potentialConnecting == next_index || potentialConnecting == convex_index || potentialConnecting == lastIndex) continue;
|
||||||
|
|
||||||
PVector potentialConnectingPoint = vertices.get(potentialConnecting);
|
PVector potentialConnectingPoint = vertices.get(potentialConnecting);
|
||||||
|
@ -285,12 +278,12 @@ class NavMesh
|
||||||
int joining_index = joiningVertex(node.polygon, convex_index);
|
int joining_index = joiningVertex(node.polygon, convex_index);
|
||||||
if (joining_index == -1) return;
|
if (joining_index == -1) return;
|
||||||
|
|
||||||
// split polygons from small index to the max index
|
|
||||||
splitMap(node, min(convex_index, joining_index), max(convex_index, joining_index));
|
splitMap(node, min(convex_index, joining_index), max(convex_index, joining_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
//creates a hashmap with key PVector and value Integer
|
//creates a hashmap with key PVector and value Integer
|
||||||
//creating a hashmap for this removes the risk of directly comparing PVectors since it should look by reference instead of value
|
|
||||||
void setVertexMap(Map map)
|
void setVertexMap(Map map)
|
||||||
{
|
{
|
||||||
//clear all lookups and map vectors
|
//clear all lookups and map vectors
|
||||||
|
@ -379,10 +372,10 @@ class NavMesh
|
||||||
frontier.add(new SearchFrontier(neighbours, first_frontier, node_dest.findCenter()));
|
frontier.add(new SearchFrontier(neighbours, first_frontier, node_dest.findCenter()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//first in frontier no longer required
|
|
||||||
frontier.remove(0);
|
frontier.remove(0);
|
||||||
//sort via lambda function
|
//sort via lambda function
|
||||||
//shorter paths have priority
|
|
||||||
frontier.sort((a,b) -> {
|
frontier.sort((a,b) -> {
|
||||||
if (a.heuristicSum() > b.heuristicSum()) return 1;
|
if (a.heuristicSum() > b.heuristicSum()) return 1;
|
||||||
else if (a.heuristicSum() < b.heuristicSum()) return -1;
|
else if (a.heuristicSum() < b.heuristicSum()) return -1;
|
||||||
|
@ -400,7 +393,7 @@ class NavMesh
|
||||||
//given a list of frontiers, create a PVector path from the start to dest
|
//given a list of frontiers, create a PVector path from the start to dest
|
||||||
ArrayList<PVector> findDestPath(PVector dest, Node node_start, ArrayList<SearchFrontier> genPath)
|
ArrayList<PVector> findDestPath(PVector dest, Node node_start, ArrayList<SearchFrontier> genPath)
|
||||||
{
|
{
|
||||||
//we're going to build this list up from the end and then reverse it.
|
|
||||||
|
|
||||||
ArrayList<PVector> res = new ArrayList<PVector>();
|
ArrayList<PVector> res = new ArrayList<PVector>();
|
||||||
//add the end
|
//add the end
|
||||||
|
|
Loading…
Reference in New Issue