BALL B = new BALL(new pt(400,800), new vec(0,0), 25); BALL P1 = new BALL(new pt( 40,120), new vec(0,0) , 5); BALL P2 = new BALL(new pt(120,120), new vec(0,0) , 5); float gravity = 0.009; float shock = 0.86; float fric = 0.999; void setup(){ size(800, 800); } void draw() { background (150,100,30); P1.paint(); P2.paint(); B.move(); B.pushOff(P1); B.pushOff(P2); B.clash(); B.paint(); if (B.stopped()) {line (mouseX,mouseY,B.C.x,B.C.y); }; }; void mousePressed() { if (B.stopped()) {B.V.x = (mouseX - B.C.x) / 70.0; B.V.y = (mouseY - B.C.y) / 70.0; }; } class BALL {pt C ; vec V ; float r; BALL (pt PC, vec PV, float pr) {C=PC; V=PV; r=pr;}; void paint() { if (V.norm() == 0) {fill(color(5,250,30));} else {fill(color(250,30,10)); } ; C.show(r); }; void move() { V.y= V.y+gravity; C.x=C.x+V.x; C.y=C.y+V.y; }; void clash (){ if (C.x>width-r) {C.x=2 * (width-r) - C.x; V.x=-V.x; V.x= V.x * shock;}; if (C.yheight-r) {C.y=2 * (height-r) - C.y; V.y=-V.y; V.y= V.y * shock;}; if ((abs(V.y)<0.5) && (abs( height - r - C.y)<1.0 )) {V.y = 0; V.x = V.x * fric; if (abs(V.x)<0.6) {V.x = 0;};}; }; void pushOff(BALL O) { if (C.vecTo(O.C).norm() < r+O.r) { vec T = V.make(); T.unit(); vec N = T.make(); N.left(); float h = dot(C.vecTo(O.C),N); float w = sqrt(sq(r+O.r)-sq(h)); T.mul(-w); N.mul(-h); T.add(N); T.unit(); T.mul(-2*dot(T,V)); V.add(T); }; }; boolean stopped() {return(V.norm()==0);}; } // end of class BALL