89 lines
2.5 KiB
Scala
89 lines
2.5 KiB
Scala
import java.awt.event.ActionEvent
|
|
import java.awt._
|
|
|
|
import javax.swing.{JFrame, JPanel, Timer}
|
|
|
|
import scala.math.{Pi, atan, cos, sin, sqrt}
|
|
|
|
object RotatingCube extends App {
|
|
|
|
class RotatingCube extends JPanel {
|
|
private val vertices: Vector[Array[Double]] =
|
|
Vector(Array(-1, -1, -1), Array(-1, -1, 1), Array(-1, 1, -1),
|
|
Array(-1, 1, 1), Array(1, -1, -1), Array(1, -1, 1), Array(1, 1, -1), Array(1, 1, 1))
|
|
|
|
private val edges: Vector[(Int, Int)] =
|
|
Vector((0, 1), (1, 3), (3, 2), (2, 0), (4, 5), (5, 7),
|
|
(7, 6), (6, 4), (0, 4), (1, 5), (2, 6), (3, 7))
|
|
|
|
setPreferredSize(new Dimension(640, 640))
|
|
setBackground(Color.white)
|
|
scale(100)
|
|
rotateCube(Pi / 4, atan(sqrt(2)))
|
|
|
|
new Timer(17, (_: ActionEvent) => {
|
|
rotateCube(Pi / 180, 0)
|
|
repaint()
|
|
}).start()
|
|
|
|
override def paintComponent(gg: Graphics): Unit = {
|
|
def drawCube(g: Graphics2D): Unit = {
|
|
g.translate(getWidth / 2, getHeight / 2)
|
|
for {edge <- edges
|
|
xy1: Array[Double] = vertices(edge._1)
|
|
xy2: Array[Double] = vertices(edge._2)
|
|
} {
|
|
g.drawLine(xy1(0).toInt, xy1(1).toInt, xy2(0).toInt, xy2(1).toInt)
|
|
g.fillOval(xy1(0).toInt -4, xy1(1).toInt - 4, 8, 8)
|
|
g.setColor(Color.black)
|
|
}
|
|
}
|
|
|
|
super.paintComponent(gg)
|
|
val g: Graphics2D = gg.asInstanceOf[Graphics2D]
|
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
|
|
drawCube(g)
|
|
}
|
|
|
|
private def scale(s: Double): Unit = {
|
|
for {node <- vertices
|
|
i <- node.indices
|
|
} node(i) *= s
|
|
}
|
|
|
|
private def rotateCube(angleX: Double, angleY: Double): Unit = {
|
|
def sinCos(x: Double) = (sin(x), cos(x))
|
|
|
|
val ((sinX, cosX), (sinY, cosY)) = (sinCos(angleX), sinCos(angleY))
|
|
|
|
for {
|
|
node <- vertices
|
|
x: Double = node(0)
|
|
y: Double = node(1)
|
|
} {
|
|
def f(p: Double, q: Double)(a: Double, b: Double) = a * p + b * q
|
|
|
|
def fx(a: Double, b: Double) = f(cosX, sinX)(a, b)
|
|
|
|
def fy(a: Double, b: Double) = f(cosY, sinY)(a, b)
|
|
|
|
node(0) = fx(x, -node(2))
|
|
val z = fx(node(2), x)
|
|
node(1) = fy(y, -z)
|
|
node(2) = fy(z, y)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
new JFrame("Rotating Cube") {
|
|
add(new RotatingCube(), BorderLayout.CENTER)
|
|
pack()
|
|
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE)
|
|
setLocationRelativeTo(null)
|
|
setResizable(false)
|
|
setVisible(true)
|
|
}
|
|
|
|
}
|