Scalaで3D
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[SCALAの記事一覧]]
&topicpath;
*目次 [#sa3690a0]
#contents
*参考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: ...
type Matrix[T] = List[ List[T] ]
type Rotation[T] = List[ T ]
def determinantZ( r: Rotation[ Double ] ): Matrix[ Do...
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[ Do...
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[ Do...
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 )
)
//ラジアンでsinを求める
def sin( d: Double ) = math.sin( math.toRadians( d ))
//ラジアンでcosを求める
def cos( d: Double ) = math.cos( math.toRadians( d ))
//アフィン変換
def affine( m: Matrix[Double] ): Point3 = {
def fusion( a: List[Double], b: List[Double], f: (D...
a.zip( b ).map( org => f( org._1, org._2 ) )
Point3( fusion( toList, List.transpose( m )(0), _*_...
fusion( toList, List.transpose( m )(1), _*_...
fusion( toList, List.transpose( m )(2), _*_...
fusion( toList, List.transpose( m )(3), _*_...
)
}
//回転
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
//3次元を2次元に変換
def P3toP2( p: Point3 ): Tuple2[Int, Int] = (
convert2d( p.x, World.axis3Depth+p.z, World.screenD...
convert2d( p.y, World.axis3Depth+p.z, World.screenD...
)
//ポリゴン生成
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 ...
addMouseMotionListener( this )
addWindowListener( new WindowAdapter {
override def windowClosing( e: WindowEvent ): Uni...
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 ...
rotated.foreach( fc => g.drawPolygon( Draw.polygonF...
}
def mouseMoved( e: MouseEvent ): Unit = {
r = List( e.getY-Draw.axis2Y, -( e.getX-Draw.axis2X...
}
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())
でマウスでグリグリできる立方体が表示されるよ。
終了行:
[[SCALAの記事一覧]]
&topicpath;
*目次 [#sa3690a0]
#contents
*参考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: ...
type Matrix[T] = List[ List[T] ]
type Rotation[T] = List[ T ]
def determinantZ( r: Rotation[ Double ] ): Matrix[ Do...
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[ Do...
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[ Do...
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 )
)
//ラジアンでsinを求める
def sin( d: Double ) = math.sin( math.toRadians( d ))
//ラジアンでcosを求める
def cos( d: Double ) = math.cos( math.toRadians( d ))
//アフィン変換
def affine( m: Matrix[Double] ): Point3 = {
def fusion( a: List[Double], b: List[Double], f: (D...
a.zip( b ).map( org => f( org._1, org._2 ) )
Point3( fusion( toList, List.transpose( m )(0), _*_...
fusion( toList, List.transpose( m )(1), _*_...
fusion( toList, List.transpose( m )(2), _*_...
fusion( toList, List.transpose( m )(3), _*_...
)
}
//回転
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
//3次元を2次元に変換
def P3toP2( p: Point3 ): Tuple2[Int, Int] = (
convert2d( p.x, World.axis3Depth+p.z, World.screenD...
convert2d( p.y, World.axis3Depth+p.z, World.screenD...
)
//ポリゴン生成
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 ...
addMouseMotionListener( this )
addWindowListener( new WindowAdapter {
override def windowClosing( e: WindowEvent ): Uni...
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 ...
rotated.foreach( fc => g.drawPolygon( Draw.polygonF...
}
def mouseMoved( e: MouseEvent ): Unit = {
r = List( e.getY-Draw.axis2Y, -( e.getX-Draw.axis2X...
}
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())
でマウスでグリグリできる立方体が表示されるよ。
ページ名: