Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

coordinate systems

By: a guest on May 18th, 2013  |  syntax: Scala  |  size: 2.63 KB  |  hits: 53  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. object Vec {
  2.   val X_AXIS = Vec(1,0)
  3.   val Y_AXIS = Vec(0,1)
  4. }
  5.  
  6. case class Vec(x: Double, y: Double) {
  7.   def dotProduct(v: Vec) = x*v.x+y*v.y
  8.   def crossProduct(v: Vec) = x*v.y-y*v.x;
  9.   def length = math.sqrt(x*x+y*y)
  10.   def rotate(theta: Double) = {
  11.       val sin = math.sin(theta);
  12.       val cos = math.cos(theta);
  13.       Vec(x*cos-y*sin,
  14.           x*sin+y*cos);
  15.   }
  16.   def rotate90 = Vec(-y, x)
  17.   def +(v: Vec) = Vec(x+v.x, y+v.y)
  18.   def -(v: Vec) = Vec(x-v.x, y-v.y)
  19.   def *(d: Double) = Vec(x*d, y*d)
  20.   def /(d: Double) = Vec(x/d, y/d)
  21.   def unary_- = Vec(-x, -y)
  22.   override def toString = f"Vec($x%.3f, $y%.3f)"
  23. }
  24.  
  25. object Matrix {
  26.   def rotationMatrix(theta: Double) = {
  27.     val v = Vec.X_AXIS.rotate(theta)
  28.     Matrix(v, v.rotate90)
  29.   }
  30.   def apply(a: Double, b: Double,
  31.             c: Double, d: Double): Matrix = Matrix(Vec(a,c), Vec(b,d))
  32. }
  33.  
  34. case class Matrix(c1: Vec, c2: Vec) {
  35.   def *(v: Vec) = c1*v.x + c2*v.y
  36.   def *(d: Double) = Matrix(c1*d, c2*d)
  37.   def determinant = c1.crossProduct(c2)
  38.   def inverse = Matrix( c2.y, -c2.x,
  39.                        -c1.y,  c1.x) * (1/determinant)
  40.   override def toString = f"Matrix(${c1.x}%.3f, ${c2.x}%.3f\n" +
  41.                           f"       ${c1.y}%.3f, ${c2.y}%.3f)"
  42. }
  43.  
  44. object CoordinateSystem {
  45.   def apply(origin: Vec, rotation: Double, scaleX: Double, scaleY: Double): CoordinateSystem =
  46.     CoordinateSystem(origin,
  47.                      Matrix(Vec.X_AXIS.rotate(rotation)*scaleX,
  48.                      Vec.Y_AXIS.rotate(rotation)*scaleY))
  49.  
  50.   def apply(origin: Vec, xAxis: Vec, yAxis: Vec): CoordinateSystem =
  51.     CoordinateSystem(origin, Matrix(xAxis, yAxis))
  52. }
  53.  
  54. case class CoordinateSystem(origin: Vec, matrix: Matrix) {
  55.   def xAxis = matrix.c1
  56.   def yAxis = matrix.c2
  57.   val inverseMatrix = matrix.inverse
  58.   def translate(v: Vec) = matrix*v + origin
  59.   def translateBack(v: Vec) = inverseMatrix*(v-origin)
  60.   def move(v: Vec) = CoordinateSystem(origin+v, matrix)
  61.   def scale(scaleX: Double, scaleY: Double) = CoordinateSystem(origin, xAxis*scaleX, yAxis*scaleY)
  62.   def rotate(angle: Double): CoordinateSystem = rotate(origin, angle)
  63.   def rotate(center: Vec, angle: Double): CoordinateSystem =
  64.     CoordinateSystem((origin-center).rotate(angle)+center,
  65.                      xAxis.rotate(angle),
  66.                      yAxis.rotate(angle))
  67. }
  68.  
  69. val cs = CoordinateSystem(Vec(500,100),
  70.                           Vec(1,1),
  71.                           Vec(-1,1))
  72.  
  73. val v = Vec(2,3)
  74. val v2 = cs.translate(v)
  75. println(v2)
  76. println(cs.translateBack(v2))
  77.  
  78. val cs2 = CoordinateSystem(Vec(200,300), math.Pi/4, 2, 2)
  79. println(cs2.translate(v))
  80.  
  81. println(cs2.scale(10,10).translate(v))