Currently I am trying to find a way to calculate restricted random rotation close to a wall/two walls/three walls.
What I do, and it works, is to find the sector of the rotation circle, which is excluded, by trigonometry between the center of rotation proj and the closest point on the wall. For two walls the sector between the corner has to be calculated as well. When the program creates a random number I restrict the full angle by the angles I calculated for the excluded sectors, so that only correct numbers are chosen.
In the picture the furthest point of the green triangle always stays between the two walls.
The issue I am having now, is that each side is now unique. If the rotation center is close to one wall and far from another, the excluded sector is large for the part of the rotation close the first wall and smaller to the second wall. That means anglevar1 and anglevar2 have to be applied at different ends of the choice of the rotation angle.
cang = random((PI-HALF_PI+anglevar1), (TWO_PI+HALF_PI-anglevar2));
In this model I can I can easily identify, which side needs what exclusion, but when I want to use it with chance encounters (think wall interactions in a box), the program would need to identify, which angle variation would need to go on which side of the random number generation based on the walls I identify as close. I don’t see an efficient way to do that. Is there one?
May way out would be to just use the largest restriction for both sides but especially in very asymmetric cases that would limit the rotation more than necessary.
int boxsize = 500;
float camangle = 90; //camera angle
float camy = 0; //up and down camera
PVector lastseg = new PVector(30, 30, -20);
PVector nextseg = new PVector(60, 30, -30);
PVector axis = new PVector();
PVector proj = new PVector();
float distance;
float planedist1;
float planedist2;
float distnew = 150;
float newangle =radians(60);
PVector planecenter0 = new PVector();
PVector planecenter1 = new PVector();
PVector planecenter2 = new PVector();
void setup() {
size(900, 700, P3D);
}
void draw() {
background(129, 200, 273);
perspective();
lights();
translate(450, 350, 0);
rotateX(camy);
rotateY(camangle);
noFill();
stroke(0);
strokeWeight(1);
box(boxsize);
if (mousePressed == true) {
camangle += 0.1;
}
if (keyPressed == true) {
if (key =='q' || key == 'Q') {
camy +=0.1;
}
if (key =='a' || key == 'A') {
camy -=0.1;
}
camangle += 0.1;
}
rectMode(CENTER);
fill(255, 100);
pushMatrix();
rect(0, 0, boxsize, boxsize);
popMatrix();
pushMatrix();
rotateX(HALF_PI);
rect(0, 0, boxsize, boxsize);
popMatrix();
pushMatrix();
stroke(125, 255, 0);
translate(lastseg.x, lastseg.y, lastseg.z);
sphere(20);
popMatrix();
pushMatrix();
translate(nextseg.x, nextseg.y, nextseg.z);
sphere(20);
popMatrix();
axis = PVector.sub(lastseg, nextseg);
float axislength = axis.mag();
distance = sqrt(2*distnew*distnew - 2*distnew*distnew*cos(newangle));
if (distance != axislength) {
PVector d = axis.copy();
d.setMag(axislength-distance);
nextseg.add(d);
}
stroke(125, 255, 0);
strokeWeight(5);
line(lastseg.x, lastseg.y, lastseg.z, nextseg.x, nextseg.y, nextseg.z);
proj = axis.copy();
proj.setMag(distance/2);
proj.add(nextseg);
//radius of rotation
float cradius = sqrt(sq(distnew)-sq(distance/2));
//Identify axis coordinate with smallest absolute value to create perpendicular vector
planecenter0 = new PVector(proj.x, 0, 0);
planecenter1 = new PVector(proj.x, proj.y, 0);
planecenter2 = new PVector(proj.x, 0, proj.z);
planedist1 = PVector.dist(planecenter1, proj);
planedist2 = PVector.dist(planecenter2, proj);
float cornerproj = PVector.dist(planecenter0, proj);
//angle between corner and planecenters excluded from rotation
float anglevarc1 = acos(planedist1/cornerproj);
float anglevarc2 = acos(planedist2/cornerproj);
//angle between planecenter and radius touching plane excluded from rotation
float anglevar1 = acos(planedist1/cradius);
float anglevar2 = acos(planedist2/cradius);
anglevar1 += anglevarc1;
anglevar2 += anglevarc2;
PVector b = PVector.sub(proj, planecenter0);
b.normalize();
//create vectors in plane with intersect circle
PVector iv = new PVector();
PVector.cross(axis, b, iv);
PVector jv = new PVector();
PVector.cross(axis, iv, jv);
iv.normalize();
jv.normalize();
PVector c2 = new PVector();
PVector c3 = new PVector();
PVector p = new PVector();
float cang = random((PI-HALF_PI+anglevar1), (TWO_PI+HALF_PI-anglevar2));
PVector.mult(iv, cos(cang), c2);
c2.mult(cradius);
PVector.mult(jv, sin(cang), c3);
c3.mult(cradius);
p.add(proj);
p.add(c2);
p.add(c3);
stroke(0, 255, 0);
strokeWeight(5);
line(proj.x, proj.y, proj.z, p.x, p.y, p.z);
line(lastseg.x, lastseg.y, lastseg.z, p.x, p.y, p.z);
line(nextseg.x, nextseg.y, nextseg.z, p.x, p.y, p.z);
stroke(120, 125, 0);
line(planecenter0.x, planecenter0.y, planecenter0.z, proj.x, proj.y, proj.z);
line(planecenter1.x, planecenter1.y, planecenter1.z, proj.x, proj.y, proj.z);
line(planecenter2.x, planecenter2.y, planecenter2.z, proj.x, proj.y, proj.z);
}