http://cs101.edu/courses/fall05/psets/revision/MysteryBall.html
/*
 * MysteryBall.java
 *
 * Lab 6.  What does this do?  How does it work?
 */

package lab6;

import ballworld.Ball;
import ballworld.World;
import cs101.anim.Animate;

public class MysteryBall implements Ball, Animate {
    MysteryBall pop;
    MysteryBall kid;
    World world;
    DoubleVector loc;
    
    static MysteryBall anchor;

    public MysteryBall() {
        loc = new DoubleVector();
    }
    
    public MysteryBall(MysteryBall dad) {
        pop = dad;
        dad.kid = this;
        loc = new DoubleVector();
    }

    public void userTyped(char ch) {
        if (ch==" ") {
            MysteryBall scan = this;
            while (scan.kid != null) {
                scan = scan.kid;
            }
            MysteryBall newkid = new MysteryBall(scan);
            world.addBall(newkid);
        }
    }

    public void setWorld(World world) {
        this.world = world;
    }

    public void userDragged(double xLoc, double yLoc) {
        loc.x = xLoc;
        loc.y = yLoc;
        anchor = this;
    }

    public double getX() {
        return loc.x;
    }

    public double getY() {
        return loc.y;
    }

    public double getRadius() {
        return 10;
    }

    public void act() {
        DoubleVector popPull = new DoubleVector();
        DoubleVector kidPull = new DoubleVector();
        Ball closest = world.getClosestBall(this);
        if (closest != null && this != anchor) {
            double dx = loc.x - closest.getX();
            double dy = loc.y - closest.getY();
            double dist = Math.sqrt(dx*dx + dy*dy);
            if (dist == 0) {
                dist = 1;
            }
            if (dist<40) {
                loc.x += dx/dist;
                loc.y += dy/dist;
            }
        }
        if (pop!=null) {
            double dx = loc.x-pop.loc.x;
            double dy = loc.y-pop.loc.y;
            double dist = Math.sqrt(dx*dx+dy*dy);
            if (dist == 0) {
                dist = 1;
            }
            popPull.x = pop.loc.x + dx*20/dist;
            popPull.y = pop.loc.y + dy*20/dist;
        } else {
            popPull.x = loc.x;
            popPull.y = loc.y;
        }
        if (kid!=null) {
            double dx = loc.x-kid.loc.x;
            double dy = loc.y-kid.loc.y;
            double dist = Math.sqrt(dx*dx+dy*dy);
            if (dist == 0) {
                dist = 1;
            }
            kidPull.x = kid.loc.x + dx*20/dist;
            kidPull.y = kid.loc.y + dy*20/dist;
        } else {
            kidPull.x = loc.x;
            kidPull.y = loc.y;
        }
        if (anchor != null && anchor == pop) {
            loc.x = popPull.x;
            loc.y = popPull.y;
        }
        if (anchor != null && anchor == kid) {
            loc.x = kidPull.x;
            loc.y = kidPull.y;
        }
        if (anchor == null || (anchor != kid && anchor != pop)) {
            loc.x = (kidPull.x+popPull.x)/2;
            loc.y = (kidPull.y+popPull.y)/2;
        }
    }
    
    
}