AnalogueCuboid.scala
package net.snowtiger.analogue
import java.lang.StringBuilder
/**
* An AnalogueCuboid provides a way of creating a triplet of natural numbers
* (width, height, depth) using a pictographic representation.
* See http://snowtiger.net/scala/analogue for a complete article on the subject.
*
* Note that the base class companion object must be imported
* (using import AnalogueLiteral._) in order to use the required constants and
* implicit type conversions.
*
* @author Mark B Davies
*/
class AnalogueCuboid(x: Int, y: Int, z: Int) extends AnalogueLiteral
{
val width = floor(x)
val height = floor(y)
val depth = floor(z)
def volume = width*height*depth
override def equals(obj: Any) =
{
obj match
{
case other:AnalogueCuboid =>
width==other.width && height==other.height && depth==other.depth
case _ => false
}
}
def top = new AnalogueRectangle(width, depth)
def side = new AnalogueRectangle(depth, height)
def front = new AnalogueRectangle(width, height)
// Cube construction
def incDepth() = new AnalogueCuboid(width, height, depth+1)
def \(other: AnalogueLine) = incDepth()
def \!(other: AnalogueLine) = incDepth()
def \+(other: AnalogueLine) = incDepth()
def |(other: AnalogueCuboid) =
new AnalogueCuboid(width, height+other.height+1, other.depth)
def |+(other: AnalogueCuboid) =
new AnalogueCuboid(width, height+other.height+1, other.depth)
def |!(other: AnalogueCuboid) =
new AnalogueCuboid(width, height+other.height+1, other.depth)
def !(other: AnalogueLine) = incDepth()
def !~(other: AnalogueLine) = incDepth()
def !~~(other: AnalogueLine) = incDepth()
def !~~~(other: AnalogueLine) = incDepth()
def !~~~~(other: AnalogueLine) = incDepth()
def !~~~~~(other: AnalogueLine) = incDepth()
def !~~~~~~(other: AnalogueLine) = incDepth()
def !~~~~~~~(other: AnalogueLine) = incDepth()
def !~~~~~~~~(other: AnalogueLine) = incDepth()
def !~~~~~~~~~(other: AnalogueLine) = incDepth()
def ~(other: AnalogueLine) = this
def ~~(other: AnalogueLine) = this
def ~~~(other: AnalogueLine) = this
def ~~~~(other: AnalogueLine) = this
def ~~~~~(other: AnalogueLine) = this
def ~~~~~~(other: AnalogueLine) = this
def ~~~~~~~(other: AnalogueLine) = this
def ~~~~~~~~(other: AnalogueLine) = this
def ~~~~~~~~~(other: AnalogueLine) = this
// Arithmetic operations on cuboids
def +(other: AnalogueCuboid) =
new AnalogueCuboid(width+other.width, height+other.height, depth+other.depth)
def +(other: Int) = new AnalogueCuboid(width+other, height+other, depth+other)
def *(other: Int) = new AnalogueCuboid(width*other, height*other, depth*other)
def sizeString =
{
"("+width+"x"+height+"x"+depth+")=" + volume
}
def pictureString =
{
val lineString = new AnalogueLine(width).pictureString();
val s = new StringBuilder(lineString)
s.append("\n")
var i = 1
// Outputs lines of format: | + L
while (i < depth.min(height+1))
{
s.append("|").append(" "*(i-1)).append("+")
s.append(" "*(width-1)).append("L\n")
i+= 1
}
var j = 1
// Outputs lines of format: \ + L
while (i < depth)
{
s.append(" "*j).append("\\").append(" "*(height-1))
s.append("+").append(" "*(width-1)).append("L\n")
i+= 1; j+= 1
}
// Outputs middle line, \ O~~~I or | O~~~I
if (i < height+1)
{
s.append("|").append(" "*(depth-1))
}
else
{
s.append(" "*j).append("\\").append(" "*(height-1))
j+= 1
}
s.append(lineString).append("\n")
i+= 1
// Outputs lines of format: | ! I
while (i < height+1)
{
s.append("|").append(" "*(depth-1)).append("!")
s.append(" "*(width-1)).append("I\n")
i+= 1
}
// Outputs lines of format: \ ! I
while (i < depth+height)
{
s.append(" "*j).append("\\").append(" "*(depth-j-1))
s.append("!").append(" "*(width-1)).append("I\n")
i+= 1; j+= 1
}
s.append(" "*j).append("!").append(lineString.substring(1))
s.toString
}
}