5

What's the best way to implement Affine Transformations in Scala? There don't seem to be any in the standard library or in Spire. The AWT AffineTransformation class is horribly mutable and I definitely don't want to mutate the Graphics2D class. Is it more efficient to write my own or to wrap the Java class in value returning functions, or is there already a suitable Scala library?

Edit: I don't think the basic equations are too challenging to code. The complication seem to be adding special cases for 90/180/270 rotations and dealing with int/ double/ float conversions for a comprehensive solution.

0__
  • 66,707
  • 21
  • 171
  • 266
Rich Oliver
  • 6,001
  • 4
  • 34
  • 57
  • 1
    I'd suggest to wrap AWT's AffineTransform. It would definitely take much less time than rolling your own. – Rogach Nov 12 '12 at 12:24

1 Answers1

2

I agree with the comment, don't invest the effort to implement the formulas yourself.

import java.awt.geom.{AffineTransform => JTransform}

object AffineTransform {
   implicit def toJava(at: AffineTransform): JTransform = at.toJava
   implicit def fromJava(j: JTransform): AffineTransform = {
      import j._
      AffineTransform(getScaleX,     getShearY,
                      getShearX,     getScaleY,
                      getTranslateX, getTranslateY)
   }
   val identity: AffineTransform = new JTransform()
}
final case class AffineTransform(scaleX:     Double, shearY:     Double,
                                 shearX:     Double, scaleY:     Double,
                                 translateX: Double, translateY: Double) {

   def toJava: JTransform = new JTransform(scaleX,     shearY,
                                           shearX,     scaleY,
                                           translateX, translateY)

   override def toString = "AffineTransform[[" + 
      scaleX + ", " + shearX + ", " + translateX + "], [" +
      shearY + ", " + scaleY + ", " + translateY + "]]"

   def scale(sx: Double, sy: Double): AffineTransform = {
      val j = toJava; j.scale(sx, sy); j
   }
   // ... etc
}

Test:

AffineTransform.identity.scale(0.5, 1.0)
0__
  • 66,707
  • 21
  • 171
  • 266
  • That's neat. And there's no reason why I can't implement some methods directly while using the Java class for the remainder. – Rich Oliver Nov 13 '12 at 12:29