@@ -0,0 +1,111 @@ | |||
class Citizen { | |||
int i_xSpawn, i_ySpawn, i_xPos, i_yPos, i_diameter; | |||
boolean b_linked; | |||
boolean b_moving; | |||
int i_home; | |||
String S_name; | |||
GraphNode startNode, endNode; | |||
int startNodeID, endNodeID; | |||
GraphNode[] rNodes; | |||
//GraphEdge[] exploredEdges; | |||
IGraphSearch pathFinder; | |||
int pathAlgorithm = i_pathAlgorithm; | |||
//0-100: | |||
//motivation (bei arbeiter montag ~40, freitag ~80 - 100) | |||
//7 emotionen? | |||
// berufsfeld: webdesigner, pädagoge, schmuckdesigner, schmied | |||
// berufsstatus: beamter, selbstständiger, unternehmer, angestellter, grundschüler, gymnasiast, hauptschüler, realschüler, azubi, student, rentner | |||
// identität: gelbhemd, lokal, regional, national, international, fremd, | |||
//names of pathfinding algorithms: greedy best first search, uniform cost search, a star search | |||
Citizen(int home, String name) { | |||
i_home = home; | |||
S_name = name; | |||
i_diameter = 15; | |||
pathFinder = makePathFinder(gs, pathAlgorithm); | |||
} | |||
void spawn(int house) { | |||
PVector v2_spawnPoint = houses.get(house).v2_randomSpawnPoint(); | |||
i_xSpawn = int(v2_spawnPoint.x); | |||
i_ySpawn = int(v2_spawnPoint.y); | |||
i_xPos = i_xSpawn; | |||
i_yPos = i_ySpawn; | |||
goTo(int(random(0, width)), int(random(0, height))); | |||
b_linked = true; | |||
} | |||
void despawn() { | |||
b_linked = false; | |||
} | |||
void update() { | |||
if(b_moving) { //if rNodes.length > 0 | |||
println(rNodes[0].x()); | |||
} | |||
if (rNodes.length == 0){ //rNodes needs to be an array list | |||
b_moving = false; | |||
} | |||
} | |||
void display() { | |||
ellipse(i_xPos, i_yPos, i_diameter, i_diameter); | |||
textSize(10); | |||
text(S_name, i_xPos, i_yPos-10); | |||
//draw Route | |||
if (rNodes.length >= 2) { | |||
pushStyle(); | |||
stroke(color(100, 100, 100)); | |||
strokeWeight(1); | |||
noFill(); | |||
for (int i = 1; i < rNodes.length; i++) | |||
line(rNodes[i-1].xf(), rNodes[i-1].yf(), rNodes[i].xf(), rNodes[i].yf()); | |||
stroke(160, 0, 0); | |||
fill(255, 0, 0); | |||
ellipse(rNodes[rNodes.length-1].xf(), rNodes[rNodes.length-1].yf(), nodeSize, nodeSize); | |||
popStyle(); | |||
} | |||
} | |||
void goTo(int x, int y) { | |||
//add: go to node? go to house? | |||
float nodeDistance = 1.0f; | |||
while (gs.getNodeAt(i_xPos, i_yPos, 0, nodeDistance) == null) { | |||
nodeDistance++; | |||
} | |||
startNodeID = gs.getNodeAt(i_xPos, i_yPos, 0, nodeDistance).id(); | |||
nodeDistance = 1.0f; | |||
while (gs.getNodeAt(x, y, 0, nodeDistance) == null) { | |||
nodeDistance++; | |||
} | |||
endNodeID = gs.getNodeAt(x, y, 0, nodeDistance).id(); | |||
//usePathFinder(startNodeID, endNodeID); | |||
pathFinder.search(startNodeID, endNodeID, true); //returns null if no route is found | |||
rNodes = pathFinder.getRoute(); | |||
if(rNodes.length > 0) b_moving = true; | |||
//exploredEdges = pathFinder.getExaminedEdges(); | |||
} | |||
//void usePathFinder(int startNodeID, int endNodeID) { | |||
// pathFinder.search(startNodeID, endNodeID, true); | |||
// rNodes = pathFinder.getRoute(); | |||
// exploredEdges = pathFinder.getExaminedEdges(); | |||
//} | |||
} |
@@ -3,29 +3,28 @@ import pathfinder.*; | |||
PImage img_houses; | |||
PImage img_streets; | |||
PImage img_spawnPoints; | |||
int i_biggestHouse; | |||
int i_biggestHouseSize; | |||
ArrayList<SpawnArea> spawnAreas = new ArrayList<SpawnArea>(); | |||
ArrayList<House> houses = new ArrayList<House>(); | |||
void initHouses() { | |||
img_houses.loadPixels(); | |||
for (int x = 0; x < img_houses.width; x++) { | |||
for (int y = 0; y < img_houses.height; y++) { | |||
if (int(red(img_houses.pixels[y*img_houses.width+x])) == 187) { //red must be 187 for a pixel to be part of a house | |||
spawnAreas.add(new SpawnArea(x, y)); | |||
houses.add(new House(x, y)); | |||
img_houses.updatePixels(); | |||
img_houses.loadPixels(); | |||
} | |||
} | |||
} | |||
img_houses.updatePixels(); | |||
for(SpawnArea spawn : spawnAreas){ | |||
spawn.i_size = int(map(spawn.i_size,0,i_biggestHouse,0,100)); | |||
for(House house : houses){ | |||
house.i_size = int(map(house.i_size,0,i_biggestHouseSize,0,100)); | |||
} | |||
} | |||
class SpawnArea { | |||
class House { | |||
PVector v2_center; | |||
int i_size; | |||
int i_ID; | |||
@@ -34,6 +33,8 @@ class SpawnArea { | |||
//text(i_size,v2_center.x,v2_center.y); | |||
text(i_ID,v2_center.x,v2_center.y); | |||
} | |||
ArrayDeque<PVector> v2d_selected = new ArrayDeque<PVector>(); | |||
ArrayList<PVector> v2d_points = new ArrayList<PVector>(); | |||
boolean isToSelect(int px, int py, int[] pxl, int pw, int ph, int orgColor) { | |||
@@ -45,8 +46,8 @@ class SpawnArea { | |||
return v2d_points.get(int(random(0,v2d_points.size()))); | |||
} | |||
SpawnArea(int startX, int startY) { | |||
i_ID = spawnAreas.size(); | |||
House(int startX, int startY) { | |||
i_ID = houses.size(); | |||
int [] pxl = img_houses.pixels; | |||
int pw = img_houses.width; | |||
int ph = img_houses.height; | |||
@@ -79,9 +80,7 @@ class SpawnArea { | |||
avgPoint.x = avgPoint.x/i_size; | |||
avgPoint.y = avgPoint.y/i_size; | |||
v2_center = avgPoint; | |||
if(i_size > i_biggestHouse) i_biggestHouse = i_size; | |||
if(i_size > i_biggestHouseSize) i_biggestHouseSize = i_size; | |||
} | |||
} |
@@ -1,94 +1,44 @@ | |||
import pathfinder.*; | |||
Graph gs; | |||
GraphNode[] gNodes, rNodes; | |||
GraphEdge[] gEdges, exploredEdges; | |||
int start, end; | |||
int pathAlgorithm = 3; | |||
GraphNode[] gNodes; | |||
GraphEdge[] gEdges; | |||
float nodeSize; | |||
IGraphSearch pathFinder; | |||
GraphNode startNode, endNode; //put inside citizen-class | |||
boolean selectMode = false; //put inside citizen-class, only for manual interference | |||
void initPathFinding() { | |||
//generate a public path finding graph and get nodemap | |||
img_nodes = createImage(img_houses.width, img_houses.height, ARGB); | |||
nodeSize = 5.0f; | |||
gs = new Graph(); | |||
makeGraphFromImage(gs, img_houses, int(img_houses.width * f_nodeResolution), int(img_houses.height * f_nodeResolution), true); | |||
gNodes = gs.getNodeArray(); | |||
//end = gNodes[(int) random(0, gNodes.length / 4)].id(); | |||
// do | |||
// start = gNodes[(int) random((3 * gNodes.length) / 4, gNodes.length/4)].id(); | |||
//while (start == end); | |||
gs.compact(); | |||
// Get arrays of both the nodes and edges used by the | |||
// selected graph. | |||
gNodes = gs.getNodeArray(); | |||
gEdges = gs.getAllEdgeArray(); | |||
// Create a path finder object based on the algorithm | |||
pathFinder = makePathFinder(gs, pathAlgorithm); | |||
usePathFinder(pathFinder); | |||
} | |||
void usePathFinder(IGraphSearch pf) { | |||
pf.search(start, end, true); | |||
rNodes = pf.getRoute(); | |||
exploredEdges = pf.getExaminedEdges(); | |||
} | |||
void displayPathFinding() { | |||
drawNodes(); | |||
drawRoute(rNodes, color(200, 0, 0), 5.0f); | |||
if (selectMode) { | |||
stroke(0); | |||
strokeWeight(1.5f); | |||
if (endNode != null) | |||
line(startNode.xf(), startNode.yf(), endNode.xf(), endNode.yf()); | |||
else | |||
line(startNode.xf(), startNode.yf(), mouseX, mouseY); | |||
} | |||
} | |||
//void mousePressed() { | |||
// startNode = gs.getNodeAt(mouseX, mouseY, 0, 10.0f); | |||
// if (startNode != null) | |||
// selectMode = true; | |||
//} | |||
void mousePressed() { | |||
startNode = gs.getNodeAt(mouseX, mouseY, 0, 10.0f); | |||
if (startNode != null) | |||
selectMode = true; | |||
} | |||
void mouseDragged() { | |||
if (selectMode) | |||
endNode = gs.getNodeAt(mouseX, mouseY, 0, 10.0f); | |||
} | |||
//void mouseDragged() { | |||
// if (selectMode) | |||
// endNode = gs.getNodeAt(mouseX, mouseY, 0, 10.0f); | |||
//} | |||
void mouseReleased() { | |||
if (selectMode && endNode!= null && startNode != null && startNode != endNode) { | |||
start = startNode.id(); | |||
end = endNode.id(); | |||
usePathFinder(pathFinder); | |||
} | |||
selectMode = false; | |||
startNode = endNode = null; | |||
} | |||
//void mouseReleased() { | |||
// if (selectMode && endNode!= null && startNode != null && startNode != endNode) { | |||
// start = startNode.id(); | |||
// end = endNode.id(); | |||
// usePathFinder(pathFinder); | |||
// } | |||
// selectMode = false; | |||
// startNode = endNode = null; | |||
//} | |||
@@ -190,43 +140,7 @@ void drawNodes(){ | |||
popStyle(); | |||
} | |||
void drawEdges(GraphEdge[] edges, int lineCol, float sWeight, boolean arrow){ | |||
if(edges != null){ | |||
pushStyle(); | |||
noFill(); | |||
stroke(lineCol); | |||
strokeWeight(sWeight); | |||
for(GraphEdge ge : edges){ | |||
if(arrow) { | |||
//drawArrow(ge.from(), ge.to(), nodeSize / 2.0f, 6); | |||
} else { | |||
line(ge.from().xf(), ge.from().yf(), ge.to().xf(), ge.to().yf()); | |||
} | |||
} | |||
popStyle(); | |||
} | |||
} | |||
void drawRoute(GraphNode[] r, int lineCol, float sWeight){ | |||
if(r.length >= 2){ | |||
pushStyle(); | |||
stroke(lineCol); | |||
strokeWeight(sWeight); | |||
noFill(); | |||
for(int i = 1; i < r.length; i++) | |||
line(r[i-1].xf(), r[i-1].yf(), r[i].xf(), r[i].yf()); | |||
// Route start node | |||
strokeWeight(2.0f); | |||
stroke(0,0,160); | |||
fill(0,0,255); | |||
ellipse(r[0].xf(), r[0].yf(), nodeSize, nodeSize); | |||
// Route end node | |||
stroke(160,0,0); | |||
fill(255,0,0); | |||
ellipse(r[r.length-1].xf(), r[r.length-1].yf(), nodeSize, nodeSize); | |||
popStyle(); | |||
} | |||
} | |||
void drawArrow(GraphNode fromNode, GraphNode toNode, float nodeRad, float arrowSize){ | |||
float fx, fy, tx, ty; |
@@ -1,96 +1,43 @@ | |||
Citizen[] mensch = new Citizen[3]; | |||
Citizen[] citizen = new Citizen[3]; | |||
//settings | |||
boolean b_smallerImage = true; //use a cropped, smaller version of the 1920x1080 image for faster development | |||
boolean b_loadSun = false; //load sun from web-api instead of local json file (local file is adressed to january 4th 2019. might implement a check that downloads today's information only once... | |||
boolean b_drawNodes = false; | |||
float f_nodeResolution = 0.2; //defines density of path-finding nodes, multiplied with resolution | |||
int i_pathAlgorithm = 3; | |||
//void mouseClicked(){ | |||
//mensch.goTo(112); | |||
//} | |||
class Citizen{ | |||
int i_xSpawn, i_ySpawn, i_xPos, i_yPos, i_diameter; | |||
boolean b_linked; | |||
int i_home; | |||
String S_name; | |||
//0-100: | |||
//motivation (bei arbeiter montag ~40, freitag ~80 - 100) | |||
//7 emotionen? | |||
// berufsfeld: webdesigner, pädagoge, schmuckdesigner, schmied | |||
// berufsstatus: beamter, selbstständiger, unternehmer, angestellter, grundschüler, gymnasiast, hauptschüler, realschüler, azubi, student, rentner | |||
// identität: gelbhemd, lokal, regional, national, international, fremd, | |||
//names of pathfinding algorithms: greedy best first search, uniform cost search, a star search | |||
Citizen(int home, String name){ | |||
i_home = home; | |||
S_name = name; | |||
i_diameter = 15; | |||
} | |||
void goTo(int house){ | |||
println("want to go to house " + house); | |||
} | |||
void spawn(int house){ | |||
PVector v2_spawnPoint = spawnAreas.get(house).v2_randomSpawnPoint(); | |||
i_xSpawn = int(v2_spawnPoint.x); | |||
i_ySpawn = int(v2_spawnPoint.y); | |||
i_xPos = i_xSpawn; | |||
i_yPos = i_ySpawn; | |||
b_linked = true; | |||
} | |||
void despawn(){ | |||
b_linked = false; | |||
} | |||
void mousePressed(){ | |||
citizen[0].goTo(mouseX,mouseY); | |||
void display(){ | |||
ellipse(i_xPos, i_yPos, i_diameter, i_diameter); | |||
textSize(10); | |||
text(S_name, i_xPos, i_yPos-10); | |||
} | |||
} | |||
void setup() { | |||
size(400, 300); | |||
size(1000,1000); | |||
fill(0); | |||
//ft = new SimpleDateFormat ("HH:mm:ss"); | |||
if(b_smallerImage) img_houses = loadImage(dataPath("map/houses_with_borders_small.png")); | |||
blendMode(MULTIPLY); | |||
if (b_smallerImage) img_houses = loadImage(dataPath("map/houses_with_borders_small.png")); | |||
else img_houses = loadImage(dataPath("map/houses_with_borders.png")); | |||
img_streets = loadImage(dataPath("map/streets.png")); | |||
initHouses(); | |||
blendMode(MULTIPLY); | |||
surface.setSize(img_houses.width, img_houses.height); | |||
initPathFinding(); | |||
initWeather(); | |||
mensch[0] = new Citizen(59, "Pe"); | |||
mensch[1] = new Citizen(121, "Paul"); | |||
mensch[2] = new Citizen(18, "Freddy"); | |||
surface.setSize(img_houses.width, img_houses.height); | |||
citizen[0] = new Citizen(59, "Pe"); | |||
citizen[1] = new Citizen(121, "Paul"); | |||
citizen[2] = new Citizen(18, "Freddy"); | |||
for(int i = 0; i < mensch.length; i++){ | |||
mensch[i].spawn(int(random(0,spawnAreas.size()))); | |||
for (int i = 0; i < citizen.length; i++) { | |||
citizen[i].spawn(int(random(0, houses.size()))); | |||
} | |||
//mensch[2].spawn(59); | |||
//citizen[2].spawn(59); | |||
} | |||
@@ -98,19 +45,22 @@ void setup() { | |||
void draw() { | |||
background(255); | |||
image(img_houses, 0, 0, img_houses.width, img_houses.height); | |||
//image(img_streets, 0, 0, img_houses.width, img_houses.height); | |||
textSize(7); | |||
textAlign(CENTER); | |||
for (SpawnArea spawn : spawnAreas) { | |||
spawn.display(); | |||
for (House house : houses) { | |||
house.display(); | |||
} | |||
displayPathFinding(); | |||
for (int i = 0; i < mensch.length; i++){ | |||
if(mensch[i].b_linked) mensch[i].display(); | |||
if(b_drawNodes) drawNodes(); | |||
for (int i = 0; i < citizen.length; i++) { | |||
if (citizen[i].b_linked) { | |||
citizen[i].update(); | |||
citizen[i].display(); | |||
} | |||
} | |||
UI(); | |||
} |