package automenta.spacenet.space.widget.knob;
import automenta.spacenet.space.SpaceState;
import automenta.spacenet.space.geom.Rect;
import automenta.spacenet.space.widget.window.Window;
import automenta.spacenet.var.scalar.DoubleVar;
import automenta.spacenet.var.vector.V3;
import automenta.spacenet.var.vector.V3.IfV3Changes;
public class CircleKnob extends Rect {
//in radians
public final DoubleVar angle = new DoubleVar(0.0);
private double centerRad = 0.75;
private double needleScale = 0.1;
private final Rect centerCircle;
private final Window needle = new Window();
private boolean updateNecessary = true;
public CircleKnob(SpaceState centerState, SpaceState needleState) {
super(RectShape.Empty);
centerCircle = add(new Rect(RectShape.Ellipse));
centerCircle.scale(centerRad);
centerCircle.add(centerState);
add(needle);
needle.scale(needleScale);
needle.add(needleState);
needle.getPosition().add(new IfV3Changes() {
@Override
public void onV3Changed(V3 v) {
updateNeedle();
}
});
updateNeedle();
}
protected void updateNeedle() {
if (!updateNecessary) {
return;
}
//compute angle from its position
//System.out.println("needle: " + needle.getPosition());
double a;
if ((needle.getPosition().getY() == 0) && (needle.getPosition().getX() == 0)) {
a = 0;
} else {
a = Math.atan2(needle.getPosition().getY(), needle.getPosition().getX());
}
//System.out.println(" rad: " + angle);
//constrain needle to circle acccording to position
angle.set(a);
double px = Math.cos(a) * (centerRad / 2.0 + needleScale / 2.0);
double py = Math.sin(a) * (centerRad / 2.0 + needleScale / 2.0);
updateNecessary = false;
needle.getPosition().set(px, py, 0);
updateNecessary = true;
}
public DoubleVar getAngle() {
return angle;
}
}