Skip to content

Instantly share code, notes, and snippets.

@FreedomGrenade
Last active October 14, 2015 10:05
Show Gist options
  • Save FreedomGrenade/4afcff17982c7299e683 to your computer and use it in GitHub Desktop.
Save FreedomGrenade/4afcff17982c7299e683 to your computer and use it in GitHub Desktop.
PVector circle0, circle1; // x,y = centre, z = radius
PVector para0, para1, para2, para3; // x,y = focux, z = directrix (ie y = z)
float line, flip;
public void setup() {
para0 = new PVector();
para1 = new PVector();
para2 = new PVector();
para3 = new PVector();
size(800, 800);
circle0 = new PVector(width/2, height/2, 200);
circle1 = new PVector(width/2, height/2-150, 50);
line = height/2-100;
flip = 1;
textAlign(CENTER, CENTER);
}
public void draw() {
background(255);
float rMove = (float)mouseY-height/2;
circle0.set(circle0.x,circle0.y,200-rMove);
circle1.set(circle1.x,circle1.y,50+rMove);
line = height/2.0-100+(rMove*flip);
para0.set(circle0.x, circle0.y, line-circle0.z);
para1.set(circle0.x, circle0.y, line+circle0.z);
para2.set(circle1.x, circle1.y, line-circle1.z);
para3.set(circle1.x, circle1.y, line+circle1.z);
ArrayList<PVector> points = new ArrayList<PVector>();
paraInt(para0,para2,points);
paraInt(para0,para3,points);
paraInt(para1,para2,points);
paraInt(para1,para3,points);
//draw what was
strokeWeight(1);
stroke(0,255,0);
noFill();
line(0,height/2-100,width,height/2-100);
ellipse(width/2, height/2, 400, 400);
ellipse(width/2, height/2-150, 100, 100);
//drawExtra();
strokeWeight(2);
stroke(64);
for (PVector p : points) {
circle(p);
}
strokeWeight(3);
stroke(0);
line(0,line,width,line);
stroke(255,0,0);
circle(circle0);
stroke(0,0,255);
circle(circle1);
fill(0);
text(str(rMove*flip)+" mouseClick to invert line ",0,height/2-10,width,20);
}
public void mouseReleased() {
flip = -flip;
}
public void drawExtra() {
strokeWeight(2);
stroke(0,255,0);
drawPara(para0, color(255,64,64));
drawPara(para1, color(255,64,64));
drawPara(para2, color(64,64,255));
drawPara(para3, color(64,64,255));
noFill();
}
public void circle(PVector c) {
ellipse(c.x, c.y, c.z*2.0, c.z*2.0);
}
public void drawPara(PVector p, int col) {
for (int x = 0; x < width; x++) {
set(x, (int)yAtPara(p,x), col);
}
fill(col);
stroke(col);
ellipse(p.x, p.y,2,2);
line(0,p.z,width,p.z);
}
public void paraInt(PVector a, PVector b, ArrayList<PVector> addlist) {
//(x-a.x)*(x-a.x) + a.y^2 -a.z^2 = 2*(a.y - a.z)*y
//(x-b.x)*(x-b.x) + b.y^2 -b.z^2 = 2*(b.y - b.z)*y
//(x-b.x)*(x-b.x) + bc = bd*y
//(x-b.x)*(x-b.x) + bc = bd*y
float ad = 2.0*(a.y - a.z);
float ac = a.y*a.y - (a.z*a.z);
float bd = 2.0*(b.y -b.z);
float bc = b.y*b.y - (b.z*b.z);
//XX(bd-ad)+ X2(bxad-axbd) + axaxbd +acbd -bxbxad -bcad = 0
float A = bd-ad;
float B = 2*(b.x*ad-a.x*bd);
float C = (a.x*a.x + ac)*bd - (b.x*b.x + bc)*ad;
float sq = B*B - 4*A*C;
if (sq < 0) return; // Imaginary roots
float x = (-B + sqrt(sq))/ (2*A);
float y = yAtPara(a, x);
addlist.add(new PVector(x, y, abs(y-line)));
//if (sq == 0) return; // One root
x = (-B - sqrt(sq))/ (2*A);
y = yAtPara(a, x);
addlist.add(new PVector(x, y, abs(y-line)));
}
public float yAtPara(PVector p, float x) {
float xd = x-p.x;
return (xd*xd + p.y*p.y - p.z*p.z)/(2*(p.y - p.z)); // parabola from focus + directrix
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment