improved the bridges a bit…
// https://discourse.processing.org/t/p3d-two-towers-with-a-connecting-bridge-quadstrip/14109/3
import peasy.*;
PeasyCam cam;
PShape shapeTower1, shapeBridge1;
// ------------------------------------------------------------------------
// processing core functions
void setup() {
size(1600, 800, P3D);
ortho();
noFill();
cam = new PeasyCam(this,
width/2+211, height/2-200, 40,
111);
initTower(50, 300, 50);
}
void draw() {
background(255);
avoidClipping();
// my_Camera();
lights();
// create perspective
translate(width/2, height/2, 0);
rotateX(-PI/6);
rotateY(PI/3);
// draw ground
fill(0, 255, 0);
box(600, 3, 600);
// draw scene
towerBridgeLayout(50, 300, 50,
175, 40, 20,
220);
}
// -------------------------------------------------------------
void towerBridgeLayout(float tw, float th, float tz,
float bw, float bh, float bz,
float bloft) {
// the entire scene
tower(tw, th, tz);
translate(tw/2 + bw/2, 0, 0);
bridge(bw, bh, bz, bloft);
translate(tw/2 + bw/2, 0, 0);
tower(tw, th, tz);
rotateY(-PI/2); // turn right
translate(tw/2 + bw/2, 0, 0);
bridge(bw, bh, bz, bloft);
translate(tw/2 + bw/2, 0, 0);
tower(tw, th, tz);
}
void tower(float w, float h, float d) {
/*
pushMatrix();
translate(0, -h/2, 0); // align bottom
box(w, h, d);
popMatrix();
*/
pushMatrix();
translate(0, -h, 0); // align bottom
shape(shapeTower1);
popMatrix();
}
void bridge(float w, float h, float d,
float loft) {
initBridge(w, h, int(d));
/*
pushMatrix();
translate(0, -h/2, 0); // align bottom
translate(0, -loft); // raise up
box(w, h, d);
popMatrix();
*/
pushMatrix();
translate(-w/2, -h/2, 0); // align bottom
translate(0, -loft); // raise up
//stroke(0);
//shapeBridge1.setStroke(0);
//shapeBridge1.stroke(0);
shape(shapeBridge1);
popMatrix();
}
//------------------------------------------------------------------------------
void initTower(float w, float h, int d) {
// https://de.wikipedia.org/wiki/M%C3%B6biusband
boolean grid=false;
shapeTower1=createShape();
shapeTower1.beginShape(QUAD_STRIP);
if (grid) {
// only grid
shapeTower1.noFill();
shapeTower1.stroke(0);
} else {
// full fill
shapeTower1.fill(255, 0, 0);
shapeTower1.noStroke();
// shapeTower1.stroke(0);
}
// i2 -> radius (how wide the red strip is)
// i3 / i -> alpha (angle)
for (int i2=int(h); i2>0; i2--) { // height
for (int i3=0; i3<361; i3++) { // ANGLE
int i=i3;
if (i>360)
i=i-360;
makeVertex3D(i2, i, d);
makeVertex3D(i2+1, i, d);
//
}//for
//
}//for
// ---------------------------------
shapeTower1.endShape();
}
void makeVertex3D( int i2, int i, int d ) {
float factor1 = 1;
float yadd1 = 0;
float alpha=radians(i);
PVector v = new PVector(
d*cos(alpha),
i2,
d*sin(alpha)
);
v.mult(factor1);
v.y+=yadd1;
shapeTower1.vertex(v.x, v.y, v.z);
}
//
//--------------------------------------------------------------------------------------
void initBridge(float w, float h, int d) { // width (length), height (downwards), depth (breadth of the street over the bridge)
// https://de.wikipedia.org/wiki/M%C3%B6biusband
boolean grid=false;
shapeBridge1=createShape();
shapeBridge1.beginShape(QUAD_STRIP);
if (grid) {
// only grid
shapeBridge1.noFill();
shapeBridge1.stroke(0);
} else {
// full fill
shapeBridge1.fill(255, 0, 0);
shapeBridge1.noStroke();
// shapeBridge1.stroke(0);
}
// make ArrayLists
ArrayList[] arrList = new ArrayList [6] ;
for ( ArrayList<PVector> a1 : arrList) {
a1 = new ArrayList();
}
// make ArrayLists
float depthHalf= d/2;
arrList[0] = getLine( 10, -depthHalf ); // upper left side
arrList[1] = getLine( 10, depthHalf ); // upper right
arrList[2] = getLine( 25, depthHalf ); // upper right middle
arrList[3] = getLineArc( 115, depthHalf );// lower right // arc
arrList[4] = getLineArc( 115, -depthHalf );// lower left // arc
arrList[5] = getLine( 25, -depthHalf ); // lower left right middle
// Eval ArrayLists
for (int i3=0; i3<200-1; i3++) { //
// showVertext3DBox(a1, i3);
// showVertext3DBox(a2, i3);
/* showVertext3DSphere(a3, i3);
showVertext3DSphere(a4, i3);
*/
makeVertex3D2( arrList[0], i3);
makeVertex3D2( arrList[0], i3+1);
makeVertex3D2( arrList[1], i3);
makeVertex3D2( arrList[1], i3+1);
makeVertex3D2( arrList[2], i3);
makeVertex3D2( arrList[2], i3+1);
makeVertex3D2( arrList[3], i3);
makeVertex3D2( arrList[3], i3+1);
makeVertex3D2( arrList[4], i3);
makeVertex3D2( arrList[4], i3+1);
makeVertex3D2( arrList[5], i3);
makeVertex3D2( arrList[5], i3+1);
// makeVertex3D2(a5, i3);
// makeVertex3D2(a5, i3+1);
//
}//for
//
// ---------------------------------
shapeBridge1.endShape();
}
// -----------------------------------------------
ArrayList<PVector> getLine ( float y_, float z_ ) {
// fill ArrayList with line
ArrayList<PVector> newArrayList = new ArrayList();
// make ArrayLists
for (int i3=0; i3<200; i3++) { //
// store points in list
PVector pv1 = new PVector(i3, y_, z_);
newArrayList.add(pv1);
} //for
return newArrayList;
//
}// func ---
ArrayList<PVector> getLineArc ( float y_, float z_ ) {
// fill ArrayList with Arc
ArrayList<PVector> newArrayList = new ArrayList();
// make ArrayLists
for (int i3=0; i3<200; i3++) { //
float farAngle=PI/3;
float angle=map(i3, 0, 200, -farAngle, farAngle);
angle+=radians(270);
float r = 80 ;
float x=cos(angle)*r;
float y=sin(angle)*r+y_;
// store points in list
PVector pv1 = new PVector(x+175/2, y, zValue(z_, angle));
newArrayList.add(pv1);
} //for
return newArrayList;
//
}// func ---
float zValue(float z_, float angle_) {
float factor1=3.4;
if (z_<0)
return z_-angle_*factor1;
else
return z_+angle_*factor1;
}
void makeVertex3D2( ArrayList<PVector> arrL_, int i ) {
// ArrayList version
PVector v = arrL_.get(i);
shapeBridge1.vertex(v.x, v.y, v.z);
}
// --------------------------------------------------------------------------
void showVertext3DBox( ArrayList<PVector> arrL_, int i ) {
// ArrayList version
PVector v = arrL_.get(i);
pushMatrix();
translate(50/2 + 300/2, 0, 0);
translate(v.x, v.y, v.z); //
noStroke();
fill(255, 0, 0); // RED
box(14);
popMatrix();
}
void showVertext3DSphere( ArrayList<PVector> arrL_, int i ) {
// ArrayList version
PVector v = arrL_.get(i);
pushMatrix();
translate(50/2 + 300/2, 0, 0);
translate(v.x, v.y, v.z); //
noStroke();
fill(255, 0, 0); // RED
sphere(2);
popMatrix();
}
//
// ----------------------------------------------------------------------------
// Minor tools
void my_Camera() {
// limit from +- PI to +- PI/2 like more natural view??
float x = map(mouseX, 0, width, -PI/2, PI/2);
float y = Y*map(mouseY, 0, height, -PI/2, PI/2); // invert processing Y
translate(width/2-660, height/2);
// scale(zmag);
rotateY(x);
rotateX(y);
// here the view is axis correct if mouse is middle/center of canvas!!!
// right hand rule: thumb X RIGHT (RED), point finger Y UP(GREEN), middle finger Z FRONT (BLUE)( points to you )
}
void avoidClipping() {
// avoid clipping :
// https : //
// forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
perspective(PI/3.0, (float) width/height, 1, 1000000);
}//func
// -----------------------------------------------------------------------
//