Click and drag to move points of the triangle. Press enter to toggle construction lines
xxxxxxxxxx
ArrayList<Point> tri=new ArrayList();
ArrayList<Point> MdPts=new ArrayList();
ArrayList<Point> altPts=new ArrayList();
ArrayList<Point> altMdPts=new ArrayList();
Point Ortho;
Point center;
boolean show=false;
void setup() {
size(600, 600);
background(255);
for (int i=0; i<3; i++) {
tri.add(new Point(new PVector(random(10, width-10), random(10, height-10)), 7));
}
}
void draw() {
background(255);
fill(255);
MdPts=new ArrayList();
altPts=new ArrayList();
altMdPts=new ArrayList();
if (mousePressed==true) {
for (int i=0; i<tri.size(); i++) {
if (abs(tri.get(i).pos.x-mouseX)<10 && abs(tri.get(i).pos.y-mouseY)<10) {
int a=i+1;
if (a>2)a-=3;
int b=i+2;
if (b>2)b-=3;
if (tri.get(a).movable!=true && tri.get(b).movable!=true) {
tri.get(i).movable=true;
}
}
}
for (int i=0; i<tri.size(); i++) {
if (tri.get(i).movable==true) {
tri.get(i).pos.x=mouseX;
tri.get(i).pos.y=mouseY;
}
}
}
for (int i=0; i<tri.size(); i++) {
int a=i+1;
if (a>2)a-=3;
int b=i+2;
if (b>2)b-=3;
PVector mid=PVector.lerp(tri.get(a).pos, tri.get(b).pos, 0.5);
MdPts.add(new Point(mid, 4));
if (show==true) {
strokeWeight(.25);
line(tri.get(i).pos.x, tri.get(i).pos.y, mid.x, mid.y);
}
}
float[] t1=null;
float[] t2=null;
for (int i=0; i<tri.size()-1; i++) {
int a=i+1;
if (a>2)a-=3;
float dist=MdPts.get(i).pos.dist(MdPts.get(a).pos);
if(t1==null){
t1=cirIntr(MdPts.get(i).pos.x,MdPts.get(i).pos.y,MdPts.get(a).pos.x,MdPts.get(a).pos.y,dist,dist);
}
else{
t2=cirIntr(MdPts.get(i).pos.x,MdPts.get(i).pos.y,MdPts.get(a).pos.x,MdPts.get(a).pos.y,dist,dist);
}
}
center=new Point(inter(new PVector(t1[0],t1[1]),new PVector(t1[2],t1[3]),new PVector(t2[0],t2[1]),new PVector(t2[2],t2[3])),6);
for (int i=0; i<tri.size(); i++) {
int a=i+1;
if (a>2)a-=3;
int b=i+2;
if (b>2)b-=3;
PVector a1=tri.get(i).pos;
PVector b1=tri.get(a).pos;
PVector c1=tri.get(b).pos;
PVector d1=new PVector(a1.x+cos(radians(0))*100, a1.y+sin(radians(0))*100);
float ang=getAng(a1, b1, c1);
float ang1=getAng(c1, a1, b1);
float ang2=getAng(a1, c1, d1);
float nang=ang+ang2;
nang-=ang;
ang1=(radians(90)-ang1);
nang+=ang1;
float l=cos(ang1)*c1.dist(a1);
altPts.add(new Point(new PVector(a1.x+cos((nang))*l, a1.y+sin((nang))*l),4));
if (show==true) {
strokeWeight(.25);
line(a1.x, a1.y, a1.x+cos((nang))*l, a1.y+sin((nang))*l);
}
}
Ortho= new Point(inter(tri.get(0).pos,altPts.get(0).pos,tri.get(1).pos,altPts.get(1).pos),2);
for (int i=0; i<tri.size(); i++) {
int a=i+1;
if (a>2)a-=3;
int b=i+2;
if (b>2)b-=3;
PVector mid=PVector.lerp(tri.get(i).pos, Ortho.pos, 0.5);
altMdPts.add(new Point(mid, 4));
}
strokeWeight(1);
for (int i=0; i<tri.size(); i++) {
int a=i+1;
if (a>2)a-=3;
line(tri.get(i).pos.x, tri.get(i).pos.y, tri.get(a).pos.x, tri.get(a).pos.y);
}
for (int i=0; i<tri.size(); i++) {
tri.get(i).show();
}
strokeWeight(.75);
noFill();
float dist=center.pos.dist(MdPts.get(0).pos)*2;
ellipse(center.pos.x,center.pos.y,dist,dist);
for (int i=0; i<tri.size(); i++) {
fill(255);
MdPts.get(i).show();
altPts.get(i).show();
altMdPts.get(i).show();
}
if(show){
Ortho.show();
center.show();
}
}
void mouseReleased() {
for (int i=0; i<tri.size(); i++) {
if (tri.get(i).movable==true) {
tri.get(i).movable=false;
}
}
}
void keyPressed() {
if (keyCode==ENTER) {
show= !show;
}
}
PVector inter(PVector p1, PVector p2, PVector p3, PVector p4) {
float x1 = p1.x;
float y1 = p1.y;
float x2 = p2.x;
float y2 = p2.y;
float x3 = p3.x;
float y3 = p3.y;
float x4 = p4.x;
float y4 = p4.y;
float bx = x2 - x1;
float by = y2 - y1;
float dx = x4 - x3;
float dy = y4 - y3;
float b_dot_d_perp = bx * dy - by * dx;
float cx = x3 - x1;
float cy = y3 - y1;
float t = (cx * dy - cy * dx) / b_dot_d_perp;
return new PVector(x1+t*bx, y1+t*by);
}
float getAng(PVector A, PVector B, PVector C) {
PVector AB=PVector.sub(B, A);
PVector AC=PVector.sub(C, A);
float at1=atan2(AB.y, AB.x);
float at2=atan2(AC.y, AC.x);
float ang=(at1-at2);
return ang;
}
float[] cirIntr(float x1, float y1, float x2, float y2, float r1, float r2) {
float a = x2 - x1;
float b = y2 - y1;
float ds = a*a + b*b;
float d = (float)Math.sqrt( ds );
float t = (float)Math.sqrt( ((d + r1 + r2) * (d + r1 - r2) * (d - r1 + r2) * (-d + r1 + r2) ));
float sx1 = 0.5 * (a + (a*(r1*r1 - r2*r2) + b*t)/ds);
float sx2 = 0.5 * (a + (a*(r1*r1 - r2*r2) - b*t)/ds);
float sy1 = 0.5 * (b + (b*(r1*r1 - r2*r2) - a*t)/ds);
float sy2 = 0.5 * (b + (b*(r1*r1 - r2*r2) + a*t)/ds);
sx1 += x1;
sy1 += y1;
sx2 += x1;
sy2 += y1;
float[] r = new float[4];
r[0] = sx1;
r[1] = sy1;
r[2] = sx2;
r[3] = sy2;
return r;
}
class Point {
PVector pos=new PVector();
float r;
boolean movable=false;
Point(PVector p, float tr) {
pos=p;
r=tr;
}
void show() {
strokeWeight(1);
stroke(0);
fill(0);
ellipse(pos.x, pos.y, r, r);
if (movable) {
strokeWeight(1.5);
ellipse(pos.x, pos.y, r*1.25, r*1.25);
}
}
}