@@ -1 +0,0 @@ | |||
Subproject commit 99eb89f5542b05ceaf6ccbdeb66afe47179f1f9a |
@@ -0,0 +1,150 @@ | |||
import java.lang.Double; | |||
class Citizen { | |||
int i_xSpawn, i_ySpawn, i_diameter; | |||
boolean b_linked; | |||
boolean b_moving; | |||
int i_home; | |||
String S_name; | |||
float f_xPos, f_yPos; | |||
float f_movementSpeed = 10; | |||
//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, | |||
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); | |||
f_xPos = i_xSpawn; | |||
f_yPos = i_ySpawn; | |||
rNodes = pathFinder.getRoute(); | |||
if (b_randomRun) goTo(int(random(0, width)), int(random(0, height))); | |||
b_linked = true; | |||
} | |||
void despawn() { | |||
b_linked = false; | |||
} | |||
boolean b_moveDiagonally() { | |||
if (int(rNodes[nextNode].xf()) != int(f_xPos) && int(rNodes[nextNode].yf()) != int(f_yPos)) { | |||
return true; | |||
} else { | |||
return false; | |||
} | |||
} | |||
int i_direction(float f, float v) { | |||
if (f <= 0-v) return -1; | |||
else if (f >= 0+v) return 1; | |||
else return 0; | |||
} | |||
void update() { | |||
if (b_moving) { //if rNodes.length > 0 | |||
if (rNodes.length > nextNode) { | |||
float f_xPosNext = rNodes[nextNode].xf(); | |||
float f_yPosNext = rNodes[nextNode].yf(); | |||
float f_movementVelo = f_movementSpeed; | |||
if (b_moveDiagonally()) f_movementVelo = f_movementVelo / 1.41; | |||
f_xPos += i_direction(f_xPosNext-f_xPos, f_movementVelo) * f_movementVelo; | |||
f_yPos += i_direction(f_yPosNext-f_yPos, f_movementVelo) * f_movementVelo; | |||
if (abs(f_yPos - f_yPosNext) < f_movementVelo && abs(f_xPos - f_xPosNext) < f_movementVelo) { | |||
f_yPos = f_yPosNext; | |||
f_xPos = f_xPosNext; | |||
nextNode++; | |||
} | |||
} else { | |||
b_moving = false; | |||
nextNode = 0; | |||
if (b_randomRun)goTo(int(random(0, width)), int(random(0, height))); | |||
} | |||
} | |||
} | |||
void display() { | |||
//draw Route | |||
if (rNodes.length >= 2 && (b_drawPathLine || b_drawPathDestination)) { | |||
pg_map.pushStyle(); | |||
if (b_drawPathLine) { | |||
pg_map.stroke(color(100, 100, 100)); | |||
pg_map.strokeWeight(1); | |||
pg_map.noFill(); | |||
for (int i = 1; i < rNodes.length; i++) | |||
pg_map.line(rNodes[i-1].xf(), rNodes[i-1].yf(), rNodes[i].xf(), rNodes[i].yf()); | |||
} | |||
if (b_drawPathDestination) { | |||
pg_map.stroke(160, 0, 0); | |||
pg_map.fill(255, 0, 0); | |||
pg_map.ellipse(rNodes[rNodes.length-1].xf(), rNodes[rNodes.length-1].yf(), nodeSize, nodeSize); | |||
} | |||
pg_map.popStyle(); | |||
} | |||
pg_map.ellipse(f_xPos, f_yPos, i_diameter, i_diameter); | |||
pg_map.textSize(10); | |||
pg_map.text(S_name, f_xPos, f_yPos-10); | |||
} | |||
GraphNode startNode, endNode; | |||
int startNodeID, endNodeID; | |||
GraphNode[] rNodes; | |||
ArrayList<GraphNode> rNodesList = new ArrayList<GraphNode>(); | |||
int nextNode; | |||
IGraphSearch pathFinder; | |||
int pathAlgorithm = i_pathAlgorithm; | |||
void goTo(int x, int y) { | |||
//add: go to node? go to house? | |||
float nodeDistance = 1.0f; | |||
while (gs.getNodeAt(f_xPos, f_yPos, 0, nodeDistance) == null) { | |||
nodeDistance++; | |||
} | |||
startNodeID = gs.getNodeAt(f_xPos, f_yPos, 0, nodeDistance).id(); | |||
nodeDistance = 1.0f; | |||
while (gs.getNodeAt(x, y, 0, nodeDistance) == null) { | |||
nodeDistance++; | |||
} | |||
endNodeID = gs.getNodeAt(x, y, 0, nodeDistance).id(); | |||
pathFinder.search(startNodeID, endNodeID, true); //returns null if no route is found | |||
rNodes = pathFinder.getRoute(); | |||
if (rNodes.length > 0) { | |||
nextNode = 0; | |||
b_moving = true; | |||
for (int i = 0; i < rNodes.length; i++) { | |||
rNodesList.add(rNodes[i]); | |||
} | |||
} else { | |||
if (b_randomRun) goTo(int(random(0, width)), int(random(0, height))); | |||
} | |||
} | |||
} |
@@ -0,0 +1,89 @@ | |||
import java.util.ArrayDeque; | |||
import pathfinder.*; | |||
PImage img_houses; | |||
PImage img_streets; | |||
PGraphics pg_map; | |||
int i_mapOffsetX, i_mapOffsetY, i_offsetStartX, i_offsetStartY; | |||
int i_biggestHouseSize; | |||
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 | |||
houses.add(new House(x, y)); | |||
img_houses.updatePixels(); | |||
img_houses.loadPixels(); | |||
} | |||
} | |||
} | |||
img_houses.updatePixels(); | |||
for (House house : houses) { | |||
house.i_size = int(map(house.i_size, 0, i_biggestHouseSize, 0, 100)); | |||
} | |||
} | |||
class House { | |||
PVector v2_center; | |||
int i_size; | |||
int i_ID; | |||
void display() { | |||
//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) { | |||
if (px < 0 || px >= pw || py < 0 || py >= ph) | |||
return false; | |||
return pxl[px + py * pw] == orgColor; | |||
} | |||
PVector v2_randomSpawnPoint() { | |||
return v2d_points.get(int(random(0, v2d_points.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; | |||
int orgColor = pxl[startX + startY * pw]; | |||
PVector v2_p = new PVector(startX, startY); | |||
//color randCol = color(int(random(0, 255)), int(random(0, 255)), int(random(0, 255))); | |||
v2d_selected.add(v2_p); | |||
int west, east; | |||
while (!v2d_selected.isEmpty () ) { //&& q.size() < 500) { | |||
v2_p = v2d_selected.removeFirst(); | |||
if (isToSelect(int(v2_p.x), int(v2_p.y), pxl, pw, ph, orgColor)) { | |||
west = east = int(v2_p.x); | |||
while (isToSelect(--west, int(v2_p.y), pxl, pw, ph, orgColor)); | |||
while (isToSelect(++east, int(v2_p.y), pxl, pw, ph, orgColor)); | |||
for (int x = west + 1; x < east; x++) { | |||
v2d_points.add(new PVector(x, int(v2_p.y))); | |||
pxl[x + int(v2_p.y) * pw] = color(188, 188, 188); //important for not selecting the same area more than once | |||
if (isToSelect(x, int(v2_p.y) - 1, pxl, pw, ph, orgColor)) | |||
v2d_selected.add(new PVector(x, int(v2_p.y) - 1)); | |||
if (isToSelect(x, int(v2_p.y) + 1, pxl, pw, ph, orgColor)) | |||
v2d_selected.add(new PVector(x, v2_p.y + 1)); | |||
} | |||
} | |||
} | |||
i_size = v2d_points.size(); | |||
PVector avgPoint = new PVector(0, 0); | |||
for (PVector point : v2d_points) { | |||
avgPoint.add(point); | |||
} | |||
avgPoint.x = avgPoint.x/i_size; | |||
avgPoint.y = avgPoint.y/i_size; | |||
v2_center = avgPoint; | |||
if (i_size > i_biggestHouseSize) i_biggestHouseSize = i_size; | |||
} | |||
} |
@@ -0,0 +1,181 @@ | |||
import pathfinder.*; | |||
Graph gs; | |||
GraphNode[] gNodes; | |||
GraphEdge[] gEdges; | |||
float nodeSize; | |||
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(); | |||
gs.compact(); | |||
gNodes = gs.getNodeArray(); | |||
gEdges = gs.getAllEdgeArray(); | |||
} | |||
//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 mouseReleased() { | |||
// if (selectMode && endNode!= null && startNode != null && startNode != endNode) { | |||
// start = startNode.id(); | |||
// end = endNode.id(); | |||
// usePathFinder(pathFinder); | |||
// } | |||
// selectMode = false; | |||
// startNode = endNode = null; | |||
//} | |||
PImage img_nodes; | |||
void makeGraphFromImage(Graph g, PImage map, int tilesX, int tilesY, boolean allowDiagonals) { | |||
img_nodes.loadPixels(); | |||
for (int i = 0; i < img_nodes.pixels.length; i++) { | |||
if (map.pixels[i] != -1) { | |||
img_nodes.pixels[i] = int(color(0)); | |||
} else { | |||
img_nodes.pixels[i] = int(color(255)); | |||
} | |||
} | |||
img_nodes.updatePixels(); | |||
int dx = (img_nodes.width / tilesX) +1; | |||
int dy = (img_nodes.height / tilesY) +1; | |||
int sx = dx / 2, sy = dy / 2; | |||
// use deltaX to avoid horizontal wrap around edges | |||
int deltaX = tilesX + 1; // must be > tilesX | |||
float hCost = dx, vCost = dy, dCost = sqrt(dx*dx + dy*dy); | |||
float cost = 0; | |||
int px, py, nodeID, col; | |||
GraphNode aNode; | |||
py = sy; | |||
for (int y = 0; y < tilesY; y++) { | |||
nodeID = deltaX * y + deltaX; | |||
px = sx; | |||
for (int x = 0; x < tilesX; x++) { | |||
// Calculate the cost | |||
col = img_nodes.get(px, py) & 0xFF; | |||
cost = 1; | |||
// If col is not black then create the node and edges | |||
if (col != 0) { | |||
aNode = new GraphNode(nodeID, px, py); | |||
g.addNode(aNode); | |||
if (x > 0) { | |||
g.addEdge(nodeID, nodeID - 1, hCost * cost); | |||
if (allowDiagonals) { | |||
g.addEdge(nodeID, nodeID - deltaX - 1, dCost * cost); | |||
g.addEdge(nodeID, nodeID + deltaX - 1, dCost * cost); | |||
} | |||
} | |||
if (x < tilesX -1) { | |||
g.addEdge(nodeID, nodeID + 1, hCost * cost); | |||
if (allowDiagonals) { | |||
g.addEdge(nodeID, nodeID - deltaX + 1, dCost * cost); | |||
g.addEdge(nodeID, nodeID + deltaX + 1, dCost * cost); | |||
} | |||
} | |||
if (y > 0) | |||
g.addEdge(nodeID, nodeID - deltaX, vCost * cost); | |||
if (y < tilesY - 1) | |||
g.addEdge(nodeID, nodeID + deltaX, vCost * cost); | |||
} | |||
px += dx; | |||
nodeID++; | |||
} | |||
py += dy; | |||
} | |||
} | |||
IGraphSearch makePathFinder(Graph graph, int pathFinder) { | |||
IGraphSearch pf = null; | |||
float f = 1.0f; | |||
switch(pathFinder) { | |||
case 0: | |||
pf = new GraphSearch_DFS(gs); | |||
break; | |||
case 1: | |||
pf = new GraphSearch_BFS(gs); | |||
break; | |||
case 2: | |||
pf = new GraphSearch_Dijkstra(gs); | |||
break; | |||
case 3: | |||
pf = new GraphSearch_Astar(gs, new AshCrowFlight(f)); | |||
break; | |||
case 4: | |||
pf = new GraphSearch_Astar(gs, new AshManhattan(f)); | |||
break; | |||
} | |||
return pf; | |||
} | |||
void drawNodes(){ | |||
pg_map.pushStyle(); | |||
pg_map.noStroke(); | |||
pg_map.fill(255,0,255,72); | |||
for(GraphNode node : gNodes) | |||
pg_map.ellipse(node.xf(), node.yf(), nodeSize, nodeSize); | |||
pg_map.popStyle(); | |||
} | |||
void drawArrow(GraphNode fromNode, GraphNode toNode, float nodeRad, float arrowSize){ | |||
float fx, fy, tx, ty; | |||
float ax, ay, sx, sy, ex, ey; | |||
float awidthx, awidthy; | |||
fx = fromNode.xf(); | |||
fy = fromNode.yf(); | |||
tx = toNode.xf(); | |||
ty = toNode.yf(); | |||
float deltaX = tx - fx; | |||
float deltaY = (ty - fy); | |||
float d = sqrt(deltaX * deltaX + deltaY * deltaY); | |||
sx = fx + (nodeRad * deltaX / d); | |||
sy = fy + (nodeRad * deltaY / d); | |||
ex = tx - (nodeRad * deltaX / d); | |||
ey = ty - (nodeRad * deltaY / d); | |||
ax = tx - (nodeRad + arrowSize) * deltaX / d; | |||
ay = ty - (nodeRad + arrowSize) * deltaY / d; | |||
awidthx = - (ey - ay); | |||
awidthy = ex - ax; | |||
pg_map.noFill(); | |||
pg_map.strokeWeight(4.0f); | |||
pg_map.stroke(160, 128); | |||
pg_map.line(sx,sy,ax,ay); | |||
pg_map.noStroke(); | |||
pg_map.fill(48, 128); | |||
pg_map.beginShape(TRIANGLES); | |||
pg_map.vertex(ex, ey); | |||
pg_map.vertex(ax - awidthx, ay - awidthy); | |||
pg_map.vertex(ax + awidthx, ay + awidthy); | |||
pg_map.endShape(); | |||
} |
@@ -0,0 +1,69 @@ | |||
//import java.util.Date; | |||
//import java.text.SimpleDateFormat; | |||
//Date date = new Date(); | |||
//SimpleDateFormat ft; | |||
//Calendar c = Calendar.getInstance(); | |||
/* | |||
Simple DateFormat Format Codes | |||
G Era designator AD | |||
y Year in four digits 2001 | |||
M Month in year July or 07 | |||
d Day in month 10 | |||
h Hour in A.M./P.M. (1~12) 12 | |||
H Hour in day (0~23) 22 | |||
m Minute in hour 30 | |||
s Second in minute 55 | |||
S Millisecond 234 | |||
E Day in week Tuesday | |||
D Day in year 360 | |||
F Day of week in month 2 (second Wed. in July) | |||
w Week in year 40 | |||
W Week in month 1 | |||
a A.M./P.M. marker PM | |||
k Hour in day (1~24) 24 | |||
K Hour in A.M./P.M. (0~11) 10 | |||
z Time zone Eastern Standard Time | |||
' Escape for text Delimiter | |||
" Single quote | |||
Date and Time Conversion Characters | |||
Character Description Example | |||
c Complete date and time Mon May 04 09:51:52 CDT 2009 | |||
F ISO 8601 date 2004-02-09 | |||
D U.S. formatted date (month/day/year) 02/09/2004 | |||
T 24-hour time 18:05:19 | |||
r 12-hour time 06:05:19 pm | |||
R 24-hour time, no seconds 18:05 | |||
Y Four-digit year (with leading zeroes) 2004 | |||
y Last two digits of the year (with leading zeroes) 04 | |||
C First two digits of the year (with leading zeroes) 20 | |||
B Full month name February | |||
b Abbreviated month name Feb | |||
m Two-digit month (with leading zeroes) 02 | |||
d Two-digit day (with leading zeroes) 03 | |||
e Two-digit day (without leading zeroes) 9 | |||
A Full weekday name Monday | |||
a Abbreviated weekday name Mon | |||
j Three-digit day of year (with leading zeroes) 069 | |||
H Two-digit hour (with leading zeroes), between 00 and 23 18 | |||
k Two-digit hour (without leading zeroes), between 0 and 23 18 | |||
I Two-digit hour (with leading zeroes), between 01 and 12 06 | |||
l Two-digit hour (without leading zeroes), between 1 and 12 6 | |||
M Two-digit minutes (with leading zeroes) 05 | |||
S Two-digit seconds (with leading zeroes) 19 | |||
L Three-digit milliseconds (with leading zeroes) 047 | |||
N Nine-digit nanoseconds (with leading zeroes) 047000000 | |||
P Uppercase morning or afternoon marker PM | |||
p Lowercase morning or afternoon marker pm | |||
z RFC 822 numeric offset from GMT -0800 | |||
Z Time zone PST | |||
s Seconds since 1970-01-01 00:00:00 GMT 1078884319 | |||
Q Milliseconds since 1970-01-01 00:00:00 GMT 1078884319047 | |||
*/ |
@@ -0,0 +1,39 @@ | |||
int i_uiX = 0, i_uiY = 280, i_uiW = width, i_uiH = height - i_uiY; | |||
void UI() { | |||
fill(0); | |||
textSize(30); | |||
textAlign(LEFT); | |||
text(String.format("%02d",hour()) + ":" + String.format("%02d",minute()) + ":" + String.format("%02d",second()), 10, 30); | |||
textSize(15); | |||
text("FPS: " + int(frameRate), 10, 45); | |||
line(i_uiX,i_uiY,i_uiX+i_uiW, i_uiY); | |||
fill(255); | |||
rect(i_uiX, i_uiY, i_uiW, i_uiH); | |||
} | |||
boolean b_changeOffset; | |||
boolean b_hoverUI; | |||
void mousePressed() { | |||
if (mouseButton == RIGHT){ | |||
b_changeOffset = true; | |||
i_offsetStartX = mouseX - i_mapOffsetX; | |||
i_offsetStartY = mouseY - i_mapOffsetY; | |||
} | |||
if (mouseButton == LEFT) citizen[0].goTo(constrain(mouseX-i_mapOffsetX, 0, pg_map.width), constrain(mouseY-i_mapOffsetY, 0, pg_map.height)); | |||
} | |||
void mouseDragged() { | |||
if (b_changeOffset) { | |||
i_mapOffsetX = (mouseX - i_offsetStartX); | |||
i_mapOffsetY = (mouseY - i_offsetStartY); | |||
} | |||
} | |||
void mouseReleased() { | |||
b_changeOffset = false; | |||
} |
@@ -0,0 +1,33 @@ | |||
PVector v2_coordinates = new PVector(48.799337, 9.794482); //badmauer; x: latitude, y: longitude | |||
boolean b_isRaining; | |||
void initWeather(){ | |||
//sunrise / sunset API: https://sunrise-sunset.org/api | |||
JSONObject sun; | |||
if(b_loadSun) sun = loadJSONObject("https://api.sunrise-sunset.org/json?lat=" + v2_coordinates.x + " &lng=" + v2_coordinates.y); | |||
else sun = loadJSONObject(dataPath("weather/today.json")); | |||
println(sun); | |||
} | |||
/* backup json today (if api has yet to encounter limits) | |||
{ | |||
"results": { | |||
"sunrise": "7:13:29 AM", | |||
"solar_noon": "11:25:52 AM", | |||
"day_length": "08:24:45", | |||
"astronomical_twilight_end": "5:33:03 PM", | |||
"astronomical_twilight_begin": "5:18:41 AM", | |||
"sunset": "3:38:14 PM", | |||
"civil_twilight_end": "4:14:48 PM", | |||
"nautical_twilight_end": "4:54:50 PM", | |||
"civil_twilight_begin": "6:36:55 AM", | |||
"nautical_twilight_begin": "5:56:54 AM" | |||
}, | |||
"status": "OK" | |||
} | |||
*/ |
@@ -0,0 +1,74 @@ | |||
PImage img_houses; | |||
void setup() { | |||
size(400, 300); | |||
textSize(30); | |||
fill(0); | |||
img_houses = loadImage(dataPath("map/houses_with_borders.png")); | |||
surface.setSize(img_houses.width, img_houses.height); | |||
} | |||
void mousePressed() { | |||
img_houses.loadPixels(); | |||
if (int(red(img_houses.pixels[mouseY*img_houses.width+mouseX])) == 187) { | |||
println("clicked on house"); | |||
spawnAreas.add(new SpawnArea(mouseX, mouseY)); | |||
} | |||
img_houses.updatePixels(); | |||
} | |||
ArrayList<SpawnArea> spawnAreas = new ArrayList<SpawnArea>(); | |||
class SpawnArea { | |||
//simplified hull? | |||
ArrayList<PVector> v2_points = new ArrayList<PVector>(); | |||
SpawnArea(int startX, int startY) { | |||
int x = startX; | |||
int y = startY; | |||
v2_points.add(new PVector(x, y)); | |||
//while (int(red(img_houses.pixels[y*img_houses.width+x])) == 187) { | |||
// y++; | |||
// v2_points.add(new PVector(x, y)); | |||
// while (int(red(img_houses.pixels[y*img_houses.width+x])) == 187) { | |||
// v2_points.add(new PVector(x, y)); | |||
// y++; | |||
// } | |||
// y = startY; | |||
// x++; | |||
//} | |||
//x = startX-1; | |||
//y = startY+1; | |||
//while(int(red(img_houses.pixels[y*img_houses.width+x])) == 187){ | |||
// v2_points.add(new PVector(x, y)); | |||
// x--; | |||
//} | |||
} | |||
} | |||
void draw() { | |||
background(255); | |||
image(img_houses, 0, 0, img_houses.width, img_houses.height); | |||
for (SpawnArea spawn : spawnAreas) { | |||
for (PVector point : spawn.v2_points) { | |||
point(point.x, point.y); | |||
} | |||
} | |||
text(int(frameRate), 0, 30); | |||
} |
@@ -0,0 +1,90 @@ | |||
import java.util.ArrayDeque; | |||
PImage img_houses; | |||
PImage img_spawnPoints; | |||
int i_biggestHouse; | |||
ArrayList<SpawnArea> spawnAreas = new ArrayList<SpawnArea>(); | |||
void initHouses() { | |||
//get houses from image | |||
img_houses = loadImage(dataPath("map/houses_with_borders.png")); | |||
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)); | |||
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)); | |||
} | |||
} | |||
class SpawnArea { | |||
PVector v2_center; | |||
int i_size; | |||
void display(){ | |||
text(i_size,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) { | |||
if (px < 0 || px >= pw || py < 0 || py >= ph) | |||
return false; | |||
return pxl[px + py * pw] == orgColor; | |||
} | |||
SpawnArea(int startX, int startY) { | |||
int [] pxl = img_houses.pixels; | |||
int pw = img_houses.width; | |||
int ph = img_houses.height; | |||
int orgColor = pxl[startX + startY * pw]; | |||
PVector v2_p = new PVector(startX, startY); | |||
color randCol = color(int(random(0, 255)), int(random(0, 255)), int(random(0, 255))); | |||
v2d_selected.add(v2_p); | |||
int west, east; | |||
while (!v2d_selected.isEmpty () ) { //&& q.size() < 500) { | |||
v2_p = v2d_selected.removeFirst(); | |||
if (isToSelect(int(v2_p.x), int(v2_p.y), pxl, pw, ph, orgColor)) { | |||
west = east = int(v2_p.x); | |||
while (isToSelect(--west, int(v2_p.y), pxl, pw, ph, orgColor)); | |||
while (isToSelect(++east, int(v2_p.y), pxl, pw, ph, orgColor)); | |||
for (int x = west + 1; x < east; x++) { | |||
v2d_points.add(new PVector(x, int(v2_p.y))); | |||
pxl[x + int(v2_p.y) * pw] = color(188, 188, 188); //important for not selecting the same area more than once | |||
if (isToSelect(x, int(v2_p.y) - 1, pxl, pw, ph, orgColor)) | |||
v2d_selected.add(new PVector(x, int(v2_p.y) - 1)); | |||
if (isToSelect(x, int(v2_p.y) + 1, pxl, pw, ph, orgColor)) | |||
v2d_selected.add(new PVector(x, v2_p.y + 1)); | |||
} | |||
} | |||
} | |||
i_size = v2d_points.size(); | |||
PVector avgPoint = new PVector(0,0); | |||
for (PVector point : v2d_points) { | |||
avgPoint.add(point); | |||
} | |||
avgPoint.x = avgPoint.x/i_size; | |||
avgPoint.y = avgPoint.y/i_size; | |||
v2_center = avgPoint; | |||
if(i_size > i_biggestHouse) i_biggestHouse = i_size; | |||
} | |||
} |
@@ -0,0 +1,5 @@ | |||
void UI() { | |||
textSize(30); | |||
text(int(frameRate), 30, 30); | |||
} |
@@ -0,0 +1,24 @@ | |||
void setup() { | |||
size(400, 300); | |||
textAlign(CENTER); | |||
fill(0); | |||
initHouses(); | |||
surface.setSize(img_houses.width, img_houses.height); | |||
} | |||
void draw() { | |||
background(255); | |||
image(img_houses, 0, 0, img_houses.width, img_houses.height); | |||
textSize(7); | |||
for (SpawnArea spawn : spawnAreas) { | |||
spawn.display(); | |||
} | |||
UI(); | |||
} |
@@ -0,0 +1,91 @@ | |||
import java.util.ArrayDeque; | |||
PImage img; | |||
ArrayDeque<Point> q = new ArrayDeque<Point>(); | |||
public void setup() { | |||
size(400, 400, P2D); | |||
img = makeImage(); | |||
} | |||
public void draw() { | |||
background(255); | |||
image(img, 0, 0); | |||
} | |||
public void mouseClicked() { | |||
// Flood fill with random colour | |||
int c = (int)(random(1, 0xFFFFFF)) | 0xFF000000; | |||
floodFill(img, mouseX, mouseY, c); | |||
} | |||
void floodFill(PImage picture, int orgX, int orgY, int newColor) { | |||
int pw = picture.width; | |||
int ph = picture.height; | |||
if (orgX < 0 || orgX >= pw || orgY < 0 || orgY >= ph) | |||
return; | |||
picture.loadPixels(); | |||
int [] pxl = picture.pixels; | |||
int orgColor = pxl[orgX + orgY * pw]; | |||
// Stop if the color is not being changed. | |||
if (newColor == orgColor) | |||
return; | |||
// Proceed with flood fill | |||
Point p = new Point(orgX, orgY); | |||
q.add(p); | |||
int west, east; | |||
while (!q.isEmpty () ) { //&& q.size() < 500) { | |||
p = q.removeFirst(); | |||
if (isToFill(p.x, p.y, pxl, pw, ph, orgColor)) { | |||
west = east = p.x; | |||
while (isToFill(--west, p.y, pxl, pw, ph, orgColor)); | |||
while (isToFill(++east, p.y, pxl, pw, ph, orgColor)); | |||
for (int x = west + 1; x < east; x++) { | |||
pxl[x + p.y * pw] = newColor; | |||
if (isToFill(x, p.y - 1, pxl, pw, ph, orgColor)) | |||
q.add(new Point(x, p.y - 1)); | |||
if (isToFill(x, p.y + 1, pxl, pw, ph, orgColor)) | |||
q.add(new Point(x, p.y + 1)); | |||
} | |||
} | |||
} | |||
picture.updatePixels(); | |||
} | |||
// Returns true if the specified pixel requires filling | |||
boolean isToFill(int px, int py, int[] pxl, int pw, int ph, int orgColor) { | |||
if (px < 0 || px >= pw || py < 0 || py >= ph) | |||
return false; | |||
return pxl[px + py * pw] == orgColor; | |||
} | |||
// Make a simple image to test the flood fill function | |||
PImage makeImage() { | |||
PGraphics pg = createGraphics(width, height, P2D); | |||
pg.noSmooth(); | |||
pg.beginDraw(); | |||
pg.background(255); | |||
pg.fill(255, 200, 200); | |||
pg.noStroke(); | |||
pg.ellipse(width/2, height/3, 0.4f*width, 0.4f*height); | |||
pg.ellipse(width/3, height/1.8f, 0.4f*width, 0.4f*height); | |||
pg.ellipse(2*width/3, height/1.8f, 0.4f*width, 0.4f*height); | |||
pg.fill(255, 255, 200); | |||
pg.ellipse(width/2, height/2, 0.2f*width, 0.2f*height); | |||
pg.endDraw(); | |||
return pg.get(); | |||
} | |||
// Could use java.awt.Point instead | |||
class Point { | |||
int x, y; | |||
public Point(int x, int y) { | |||
this.x = x; | |||
this.y = y; | |||
} | |||
public String toString() { | |||
return "[" + x + ", " + y + "]"; | |||
} | |||
} |
@@ -0,0 +1,57 @@ | |||
PImage img; | |||
int diff; | |||
int px; | |||
color fillC; | |||
color test; | |||
void setup() | |||
{ | |||
size(400, 300); | |||
img = loadImage("map/houses_with_borders.png"); | |||
surface.setSize(img.width, img.height); | |||
stroke(255,0,0); | |||
noFill(); | |||
px = width*height; | |||
fillC = color(255,0,0); | |||
diff = 50; | |||
} | |||
int l(int x, int y){ | |||
return x + (y * width); | |||
} | |||
color[] flood(int x, int y, color[] pixel){ | |||
if(x<0 || x>= width || y < 0 || y >= height) return pixel; | |||
float rt = red(test); | |||
float gt = green(test); | |||
float bt = blue(test); | |||
float rc = red(pixel[l(x, y)]); | |||
float gc = green(pixel[l(x, y)]); | |||
float bc = blue(pixel[l(x, y)]); | |||
if(dist(rt, gt, bt, rc, gc, bc) <= diff){ | |||
println(dist(rt, gt, bt, rc, gc, bc)); | |||
pixel[l(x, y)] = fillC; | |||
pixel = flood(x+1, y, pixel); | |||
pixel = flood(x-1, y, pixel); | |||
pixel = flood(x, y+1, pixel); | |||
pixel = flood(x, y-1, pixel); | |||
} | |||
return pixel; | |||
} | |||
void draw() { | |||
if(mousePressed){ | |||
img.loadPixels(); | |||
test = img.pixels[l(mouseX, mouseY)]; | |||
img.pixels = flood(mouseX, mouseY, img.pixels); | |||
img.updatePixels(); | |||
} | |||
image(img, 0, 0, width, height); | |||
} |
@@ -0,0 +1,73 @@ | |||
Citizen mensch; | |||
PImage img_houses; | |||
void setup() { | |||
size(400, 300); | |||
fill(0); | |||
//ft = new SimpleDateFormat ("HH:mm:ss"); | |||
img_houses = loadImage(dataPath("houses_with_borders_small.png")); | |||
blendMode(MULTIPLY); | |||
surface.setSize(img_houses.width, img_houses.height); | |||
} | |||
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 display(){ | |||
ellipse(i_xPos, i_yPos, i_diameter, i_diameter); | |||
textSize(10); | |||
text(S_name, i_xPos, i_yPos-10); | |||
} | |||
} | |||
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); | |||
} |
@@ -0,0 +1,88 @@ | |||
Citizen[] citizen = new Citizen[10]; | |||
//settings | |||
boolean b_smallerImage = false; //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; | |||
boolean b_drawPathLine = false; | |||
boolean b_drawPathDestination = true; | |||
boolean b_randomRun = false; | |||
float f_nodeResolution = 0.2; //defines density of path-finding nodes, multiplied with resolution | |||
int i_pathAlgorithm = 3; | |||
//void mousePressed() { | |||
// citizen[0].goTo(constrain(mouseX, 0, img_houses.width), constrain(mouseY, 0, img_houses.height)); | |||
//} | |||
void setup() { | |||
size(400,400); | |||
//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")); | |||
pg_map = createGraphics(img_houses.width, img_houses.height); | |||
//surface.setSize(img_houses.width, img_houses.height); | |||
initHouses(); | |||
initPathFinding(); | |||
initWeather(); | |||
initCitizen(); | |||
} | |||
void initCitizen(){ | |||
//namen: ethuriel, nathaniel, loriel, samuel, aluriel, aleriel, thaliel, suriel, kaliel, | |||
citizen[0] = new Citizen(59, "Test"); | |||
citizen[1] = new Citizen(121, "Matze"); | |||
citizen[2] = new Citizen(18, "Freddy"); | |||
citizen[3] = new Citizen(59, "Korbi"); | |||
citizen[4] = new Citizen(121, "Lotte"); | |||
citizen[5] = new Citizen(18, "Reifi"); | |||
citizen[6] = new Citizen(59, "Grasso"); | |||
citizen[7] = new Citizen(121, "Nico"); | |||
citizen[8] = new Citizen(18, "Victor"); | |||
citizen[9] = new Citizen(59, "Paul"); | |||
for (int i = 0; i < citizen.length; i++) { | |||
citizen[i].spawn(int(random(0, houses.size()))); | |||
} | |||
//citizen[2].spawn(59); | |||
} | |||
void draw() { | |||
background(255); | |||
pg_map.beginDraw(); | |||
pg_map.fill(0); | |||
pg_map.image(img_houses, 0,0, img_houses.width, img_houses.height); | |||
//image(img_streets, 0, 0, img_houses.width, img_houses.height); | |||
pg_map.textSize(7); | |||
pg_map.textAlign(CENTER); | |||
//for (House house : houses) { | |||
// house.display(); | |||
//} | |||
if (b_drawNodes) drawNodes(); | |||
for (int i = 0; i < citizen.length; i++) { | |||
if (citizen[i].b_linked) { | |||
citizen[i].update(); | |||
citizen[i].display(); | |||
} | |||
} | |||
pg_map.endDraw(); | |||
image(pg_map, i_mapOffsetX, i_mapOffsetY); | |||
UI(); | |||
} |
@@ -0,0 +1,15 @@ | |||
{ | |||
"results": { | |||
"sunrise": "7:13:29 AM", | |||
"solar_noon": "11:25:52 AM", | |||
"day_length": "08:24:45", | |||
"astronomical_twilight_end": "5:33:03 PM", | |||
"astronomical_twilight_begin": "5:18:41 AM", | |||
"sunset": "3:38:14 PM", | |||
"civil_twilight_end": "4:14:48 PM", | |||
"nautical_twilight_end": "4:54:50 PM", | |||
"civil_twilight_begin": "6:36:55 AM", | |||
"nautical_twilight_begin": "5:56:54 AM" | |||
}, | |||
"status": "OK" | |||
} |
@@ -0,0 +1 @@ | |||
[ { "elementType": "geometry", "stylers": [ { "color": "#242f3e" }, { "visibility": "off" } ] }, { "elementType": "labels.text.fill", "stylers": [ { "color": "#746855" }, { "visibility": "off" } ] }, { "elementType": "labels.text.stroke", "stylers": [ { "color": "#242f3e" }, { "visibility": "off" } ] }, { "featureType": "administrative.locality", "elementType": "labels.text.fill", "stylers": [ { "color": "#d59563" } ] }, { "featureType": "landscape.man_made", "elementType": "geometry.fill", "stylers": [ { "color": "#ffffff" }, { "visibility": "off" } ] }, { "featureType": "landscape.man_made", "elementType": "geometry.stroke", "stylers": [ { "visibility": "on" } ] }, { "featureType": "poi", "stylers": [ { "visibility": "off" } ] }, { "featureType": "poi", "elementType": "labels.text.fill", "stylers": [ { "color": "#d59563" } ] }, { "featureType": "road", "stylers": [ { "visibility": "on" } ] }, { "featureType": "road", "elementType": "geometry", "stylers": [ { "color": "#000000" } ] }, { "featureType": "road", "elementType": "labels.icon", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road", "elementType": "labels.text.fill", "stylers": [ { "color": "#9ca5b3" } ] }, { "featureType": "road.arterial", "elementType": "geometry.stroke", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road.arterial", "elementType": "labels.icon", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road.arterial", "elementType": "labels.text", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road.highway", "stylers": [ { "visibility": "on" } ] }, { "featureType": "road.highway", "elementType": "geometry", "stylers": [ { "color": "#746855" } ] }, { "featureType": "road.highway", "elementType": "geometry.fill", "stylers": [ { "color": "#000000" }, { "visibility": "off" } ] }, { "featureType": "road.highway", "elementType": "geometry.stroke", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road.highway", "elementType": "labels.icon", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road.highway", "elementType": "labels.text", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road.local", "elementType": "geometry.stroke", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road.local", "elementType": "labels.icon", "stylers": [ { "visibility": "off" } ] }, { "featureType": "road.local", "elementType": "labels.text", "stylers": [ { "visibility": "off" } ] }, { "featureType": "transit", "elementType": "geometry", "stylers": [ { "color": "#2f3948" } ] }, { "featureType": "transit", "elementType": "labels.icon", "stylers": [ { "visibility": "off" } ] }, { "featureType": "transit.line", "elementType": "labels.icon", "stylers": [ { "visibility": "off" } ] }, { "featureType": "transit.station", "elementType": "labels.icon", "stylers": [ { "visibility": "off" } ] }, { "featureType": "transit.station", "elementType": "labels.text.fill", "stylers": [ { "color": "#d59563" } ] }, { "featureType": "water", "elementType": "geometry", "stylers": [ { "color": "#17263c" } ] }, { "featureType": "water", "elementType": "labels.text.fill", "stylers": [ { "color": "#515c6d" } ] }, { "featureType": "water", "elementType": "labels.text.stroke", "stylers": [ { "color": "#17263c" } ] } ] |