- 追加された行はこの色です。
- 削除された行はこの色です。
*参考URL [#e5a5b372]
http://d.hatena.ne.jp/uchida75cm/20101208/1291800041
*コード [#ie8c02a5]
package net.knserve.scala.polygon {
import java.awt.{ List => _, _ }
import java.awt.event._
object Main {
def main( args: Array[ String ] ): Unit = {
val p0 = Point3( -100, 100, -100, 1 )
val p1 = Point3( 100, 100, -100, 1 )
val p2 = Point3( 100, -100, -100, 1 )
val p3 = Point3( -100, -100, -100, 1 )
val p4 = Point3( -100, 100, 100, 1 )
val p5 = Point3( 100, 100, 100, 1 )
val p6 = Point3( 100, -100, 100, 1 )
val p7 = Point3( -100, -100, 100, 1 )
val cubic = Cubic(
Face( p0, p1, p2, p3 ),
Face( p4, p5, p6, p7 ),
Face( p0, p4, p5, p1 ),
Face( p1, p5, p6, p2 ),
Face( p2, p6, p7, p3 ),
Face( p3, p7, p4, p0 )
)
val drw = new Draw( cubic )
drw.setBackground( Color.black )
drw.setSize( 400, 400 )
drw.setVisible( true )
val thr = new Thread( drw )
thr.start
}
}
case class Point3( x: Double, y: Double, z: Double, s: Double ) {
type Matrix[T] = List[ List[T] ]
type Rotation[T] = List[ T ]
def determinantZ( r: Rotation[ Double ] ): Matrix[ Double ] = List(
List( cos(r(2)), sin(r(2)), 0, 0 ),
List( -sin(r(2)), cos(r(2)), 0, 0 ),
List( 0, 0, 1, 0 ),
List( 0, 0, 0, 1 )
)
def determinantY( r: Rotation[ Double ] ): Matrix[ Double ] = List(
List( cos(r(1)), 0, -sin(r(1)), 0 ),
List( 0, 1, 0, 0 ),
List( sin(r(1)), 0, cos(r(1)), 0 ),
List( 0, 0, 0, 1 )
)
def determinantX( r: Rotation[ Double ] ): Matrix[ Double ] = List(
List( 1, 0, 0, 0 ),
List( 0, cos(r(0)), sin(r(0)), 0 ),
List( 0, -sin(r(0)), cos(r(0)), 0 ),
List( 0, 0, 0, 1 )
)
def sin( d: Double ) = math.sin( math.toRadians( d ))
def cos( d: Double ) = math.cos( math.toRadians( d ))
def affine( m: Matrix[Double] ): Point3 = {
def fusion( a: List[Double], b: List[Double], f: (Double, Double) => Double ) =
a.zip( b ).map( org => f( org._1, org._2 ) )
Point3( fusion( toList, List.transpose( m )(0), _*_ ).foldLeft(0.0)(_+_),
fusion( toList, List.transpose( m )(1), _*_ ).foldLeft(0.0)(_+_),
fusion( toList, List.transpose( m )(2), _*_ ).foldLeft(0.0)(_+_),
fusion( toList, List.transpose( m )(3), _*_ ).foldLeft(0.0)(_+_)
)
}
def rotate( r: Rotation[ Double ] ) =
affine( determinantX( r ) ).
affine( determinantY( r ) ).
affine( determinantZ( r ) )
def toList = List( x, y, z, s )
}
case class Face( points: Point3* ) {
def toList: List[ Point3 ] = points.toList
}
case class Cubic( faces: Face* ) {
def toList: List[ Face ] = faces.toList
}
object World {
val axis3Depth = 400
val screenDepth = 320
}
object Draw {
val axis2X = 200
val axis2Y = 200
val convert2d: ( Double, Double, Double ) => Int =
( x1, L1, L2 ) => (( x1 * L2 ) / L1).toInt
def P3toP2( p: Point3 ): Tuple2[Int, Int] = (
convert2d( p.x, World.axis3Depth+p.z, World.screenDepth ),
convert2d( p.y, World.axis3Depth+p.z, World.screenDepth )
)
def polygonFactory( fc: List[Point3] ): Polygon = {
val plist = fc.map( p => P3toP2( p ) )
new Polygon(
plist.map( p => p._1 + axis2X ).toArray,
plist.map( p => p._2 + axis2Y ).toArray,
plist.length
)
}
}
class Draw( cubic: Cubic ) extends Frame with Runnable with MouseMotionListener {
addMouseMotionListener( this )
addWindowListener( new WindowAdapter {
override def windowClosing( e: WindowEvent ): Unit = {
System.exit( 0 )
}
})
val c: Cubic = cubic
var r: List[Double] = List( 0.0, 0.0, 0.0 )
override def paint( g: Graphics ): Unit = {
g.setColor( Color.white )
val rotated = c.toList.map( fc => fc.toList.map( p => p.rotate( r ) ) )
rotated.foreach( fc => g.drawPolygon( Draw.polygonFactory( fc ) ) )
}
def mouseMoved( e: MouseEvent ): Unit = {
r = List( e.getY-Draw.axis2Y, -( e.getX-Draw.axis2X ), 0.0 )
}
def mouseDragged( e: MouseEvent ): Unit = {
}
def run(): Unit = {
try {
while( true ) {
repaint
Thread.sleep( 30 )
}
} catch {
case e: InterruptedException =>
println( e.getMessage )
}
}
}
}
*実行方法 [#h09cbbc4]
上記のコードを2回ペーストする。
なぜ2回かというと、1回目ではPoint3が未定義と認識されて途中でエラーがでているからだ。
Main.main(Array())
でマウスでグリグリできる立方体が表示されるよ。