RosettaClock.scala
import java.util.Calendar;
// setup - called once
override def setup() {
size(400,400)
textFont(loadFont("CourierNew36.vlw"))
}
// draw - called every frame
override def draw() {
background(180,180,160)
val c = Calendar.getInstance
val h = c.get(Calendar.HOUR_OF_DAY)
val m = c.get(Calendar.MINUTE)
val s = c.get(Calendar.SECOND)
val x1 = 120
val x2 = 260
val x3 = 400
var y = 50;
val b1 = new Binary(h, 5).draw(g, x1, y);
val b2 = new Binary(m, 6).draw(g, x2, y);
val b3 = new Binary(s, 6).draw(g, x3, y);
y = 125
val s1 = new SkewBinary(h, 4).draw(g, x1, y);
val s2 = new SkewBinary(m, 5).draw(g, x2, y);
val s3 = new SkewBinary(s, 5).draw(g, x3, y);
y = 200
val t1 = new Ternary(h, 3).draw(g, x1, y);
val t2 = new Ternary(m, 4).draw(g, x2, y);
val t3 = new Ternary(s, 4).draw(g, x3, y);
y = 275
val y1 = new BalancedTernary(h, 4).draw(g, x1, y);
val y2 = new BalancedTernary(m, 5).draw(g, x2, y);
val y3 = new BalancedTernary(s, 5).draw(g, x3, y);
y = 350
val d1 = new Decimal(h, 2).draw(g, x1, y);
val d2 = new Decimal(m, 2).draw(g, x2, y);
val d3 = new Decimal(s, 2).draw(g, x3, y);
}
class Dot(x: int, y: int, c: int) {
def draw(pg: processing.core.PGraphics) {
if (c == 0)
pg.fill(128,128,128);
else if (c == 1)
pg.fill(0,255,0);
else if (c == 2)
pg.fill(0,0,255);
else if (c == -1)
pg.fill(255,0,0)
pg.ellipse(x, y, 16, 16);
}
}
// Class which draws a number as a series of binary bits
// @param v The number
// @param n The number of digits
class Binary(v: int, n: int) {
var bits = for (i <- 0 to n-1) yield bitColor(0 != (v & (1<<i)));
def draw(pg: processing.core.PGraphics, x: int, y: int) {
for (i <- 1 to n) {
val d = new Dot(x-20*i,y,bits(i-1));
d.draw(pg)
}
}
def bitColor(b: Boolean) = b match {
case true => 1
case false => 0
}
}
// Class which draws a number as a series of skew binary trits
// @param v The number
// @param n The number of digits
class SkewBinary(v: int, n: int) {
var trits = toTrits(v, n)
def draw(pg: processing.core.PGraphics, x: int, y: int) {
for (i <- 1 to n) {
val d = new Dot(x-20*i,y,trits(i-1));
d.draw(pg)
}
}
def toTrits(v: Int, n: Int): List[Int] = {
var trits: List[Int] = List()
var remainder = v;
for (i <- 0 until n) {
val p = (1<<(n - i)) - 1
if (remainder >= 2*p) {
trits = trits ++ List(2)
remainder -= 2*p
}
else if (remainder >= p) {
trits = trits ++ List(1)
remainder -= p;
}
else {
trits = trits ++ List(0)
}
}
trits.reverse
}
}
// Class which draws a number as a series of ternary trits
// @param v The number
// @param n The number of digits
class Ternary(v: int, n: int) {
var trits = for (i <- 0 to n-1) yield trit(v, i);
def draw(pg: processing.core.PGraphics, x: int, y: int) {
for (i <- 1 to n) {
val d = new Dot(x-20*i,y,trits(i-1));
d.draw(pg)
}
}
def trit(v: Int, n: Int) = {
val t = v / Math.pow(3,n)
val x = t.toInt
x % 3
}
}
// Class which draws a number as a series of balanced ternary trits
//
// Ported from http://blog.garritys.org/2009/07/balanced-ternary-in-matlab.html
//
// @param v The number
// @param n The number of digits
class BalancedTernary(v: int, n: int) {
var trits = toTrits(v, n)
def draw(pg: processing.core.PGraphics, x: int, y: int) {
for (i <- 1 to n) {
val d = new Dot(x-20*i,y,trits(i-1));
d.draw(pg)
}
}
def abs(v: Int) = if (v>=0) v else -v
def toTrits(v: Int, n: Int): List[Int] = {
var trits: List[Int] = List()
var target = v;
var tpos = 0
var value = 1;
var goal = abs(2*target);
while ((value<goal) && (tpos<10000)) {
value = 3*value;
tpos += 1;
}
if (target < 0) {
value = -value;
}
while (tpos >= 0) {
if (abs(target-value) < abs(target)) {
if (value > 0) {
trits = trits ++ List(1)
target = target-value;
}
else {
trits = trits ++ List(-1)
target = target-value;
}
}
else {
trits = trits ++ List(0)
}
value = value/3;
tpos -= 1
if ((target*value) < 0) {
value = -value;
}
}
// pad out with leading 0's
var i=trits.length
while (i < n) {
trits = 0 :: trits
i += 1
}
trits.reverse
}
}
// Class which draws a number as a series of decimal digits
// @param v The number
// @param n The number of digits
class Decimal(v: int, n: int) {
var digits = for (i <- 0 to n-1) yield digit(v, i);
def draw(pg: processing.core.PGraphics, x: int, y: int) {
pg.fill(0,0,0)
for (i <- 1 to n) {
pg.text(digits(i-1).toString,x-20*i - 20,y)
}
}
def digit(v: Int, n: Int) = {
val t = v / Math.pow(10,n)
val x = t.toInt
x % 10
}
}