ArrayList<LineSegment> segments0 = new ArrayList<LineSegment>();
ArrayList<LineSegment> segments1 = new ArrayList<LineSegment>();
//compute intersection points and max radius of roads (minimum value for roadExtrusion value)
double maxRadius = 0;
for(int j=0; j<is.connecting.size(); j++){
Road r = is.connecting.get(j);
double radius = r.width/2;
if(radius>maxRadius){
maxRadius = radius;
}
//calculate intersection lines
Turtle t0;
if(r.a.pos.equals(is.pos)){
t0 = new Turtle(is.pos, Math.toDegrees(Angle.angle(is.pos, r.b.pos)));
}else{
t0 = new Turtle(is.pos, Math.toDegrees(Angle.angle(is.pos, r.a.pos)));
}
Turtle t1 = new Turtle(t0.pos, t0.angle);
//move out to sides of roads
t0.turn(90);
t1.turn(-90);
t0.move(radius);
t1.move(radius);
Coordinate t0Start = new Coordinate(t0.pos);
Coordinate t1Start = new Coordinate(t1.pos);
//return to first orientation
t0.turn(-90);
t1.turn(90);
t0.move(r.width*6);
t1.move(r.width*6);
LineSegment ls0 = new LineSegment(t0Start, t0.pos);
LineSegment ls1 = new LineSegment(t1Start, t1.pos);
segments0.add(ls0);
segments1.add(ls1);
}
//compute intersections of roads extruded from center of intersection.
double[] extrusion = new double[is.connecting.size()];
//double maxDistance = -1;
for(int j=0; j<is.connecting.size(); j++){
for(int k=0; k<is.connecting.size(); k++){
if(j != k){
Coordinate c0 = segments0.get(j).intersection(segments1.get(k));
Coordinate c1 = segments1.get(j).intersection(segments0.get(k));
if(c0 != null){
double dist = c0.distance(is.pos);
if(dist>extrusion[j]){
extrusion[j] = dist;
log.log("dist: "+dist+" other");
}
}
if(c1 != null){
double dist = c1.distance(is.pos);
if(dist>extrusion[j]){
extrusion[j] = dist;
}
}
}
}
if(extrusion[j] < maxRadius) extrusion[j] = maxRadius;
for(int k=0; k<is.connecting.size(); k++){
if(is.connecting.get(k).a == is){
is.connecting.get(k).roadExtrusionA = extrusion[k];
}else{
is.connecting.get(k).roadExtrusionB = extrusion[k];
}
}
}
//create final road extrusion
LineSegment[] segments = new LineSegment[is.connecting.size()];
for(int j=0; j<is.connecting.size(); j++){
Road r = is.connecting.get(j);
double radius = r.width/2; //maybe a tad faster to load into variable?
Turtle t0;
if(r.a.pos.equals(is.pos)){
t0 = new Turtle(is.pos, Math.toDegrees(Angle.angle(is.pos, r.b.pos)));
}else{
t0 = new Turtle(is.pos, Math.toDegrees(Angle.angle(is.pos, r.a.pos)));
}
//move out from intersection and split into road width
t0.move(extrusion[j]);
t0.turn(90);
Turtle t1 = new Turtle(t0.pos, t0.angle-180);
t0.move(radius);
t1.move(radius);
segments[j] = new LineSegment(t0.pos, t1.pos);
}
//need to sort segments by angle order, then use that to generate shape. Convex hull will not work.
double[] angles = new double[segments.length]; //no ring, so no last element
//calculate all point angles
for(int j=0; j<angles.length; j++) angles[j] = Math.min(Math.PI*2-Angle.angle(is.pos, segments[j].p0),Math.PI*2-Angle.angle(is.pos, segments[j].p1));
//selection sort
for(int j=0; j<angles.length; j++){
int min = j;
for(int k=j+1; k<angles.length; k++){
if(angles[k]<angles[min]){
min = k; //remember new min
}
}
//swap min element with current element
if(min != j){
//swap angle array
double ang = angles[j];
angles[j] = angles[min];
angles[min] = ang;
//swap segment array
LineSegment tempS = segments[j];
segments[j] = segments[min];
segments[min] = tempS;
}
}
//close ring
Coordinate[] points = new Coordinate[is.connecting.size()*2+1];
for(int j=0; j<segments.length; j++){
points[j*2] = segments[j].p0;
points[j*2+1] = segments[j].p1;
}
points[points.length-1] = points[0];
//create ring
Geometry intersectionShape = gf.createLinearRing(points);
obj.startObject("intersection_"+this.hashCode());
//convert Coordinate to Vector3f
Coordinate[] cs = intersectionShape.getCoordinates();
Vector3f[] verts = new Vector3f[cs.length];
Vector3f[] vertsz = new Vector3f[cs.length];
float elevation = city.ter.get((int)is.pos.x, (int)is.pos.y);
for(int j=0; j<cs.length; j++){
verts[cs.length-j-1] = new Vector3f((float)cs[j].x,(float)cs[j].y, elevation);
vertsz[j] = new Vector3f((float)cs[j].x,(float)cs[j].y, 0);
}
for(int j=0; j<cs.length; j++){
obj.face(new Vector3f[]{new Vector3f(verts[j].x, verts[j].y, 0), new Vector3f(verts[(j+1)%cs.length].x, verts[(j+1)%cs.length].y, 0), verts[j]});
obj.face(new Vector3f[]{new Vector3f(verts[(j+1)%cs.length].x, verts[(j+1)%cs.length].y, 0), verts[(j+1)%cs.length], verts[j]});
}
obj.face(verts);
obj.face(vertsz);
obj.endObject();
}else{
//roads that have only 1 intersection
}
}
ArrayList<Road> roadList = (ArrayList<Road>) roads.queryAll();
for(int i=0; i<roadList.size(); i++){
Road r = roadList.get(i);
//make rectangle geometry with road ends as terrain height.
Vector3f a = new Vector3f((float)r.a.pos.x, (float)r.a.pos.y, city.ter.get((int)r.a.pos.x, (int)r.a.pos.y));
Vector3f b = new Vector3f((float)r.b.pos.x, (float)r.b.pos.y, city.ter.get((int)r.b.pos.x, (int)r.b.pos.y));
double ang = Angle.angle(r.a.pos, r.b.pos);