# from ruby opengl samples # author: gromit # roll teh mouse ! require "opengl" require "glut" $year = $day = 0 display = Proc.new { GL.Clear GL::COLOR_BUFFER_BIT GL.Color 1.0, 1.0, 1.0 GL.PushMatrix GLUT.WireSphere 1.0, 20, 16 # sun GL.Rotate $year, 0.0, 1.0, 0.0 GL.Translate 2.0, 0.0, 0.0 GL.Rotate $day, 0.0, 1.0, 0.0 GLUT.WireSphere 0.2, 10, 8 # planet GL.PopMatrix GLUT.SwapBuffers } reshape = Proc.new { |w, h| GL.Viewport 0, 0, w, h GL.MatrixMode GL::PROJECTION GL.LoadIdentity GLU.Perspective 60.0, w.to_f/h.to_f, 1.0, 20.0 GL.MatrixMode GL::MODELVIEW GL.LoadIdentity GLU.LookAt 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 } keyboard = Proc.new { |key, x, y| case key when ?d: $day = ($day + 10) % 360 when ?D: $day = ($day - 10) % 360 when ?y: $year = ($year + 5) % 360 when ?Y: $year = ($year - 5) % 360 when 27: exit else next end GLUT.PostRedisplay } require 'enumerator' require 'rational' mousepos = [] motion = Proc.new { |x, y| mousepos << [x, y] next if mousepos.length <= 10 mousepos.shift # eliminate old mousepos # calc mean of each consecutive triplet's angle angle = mousepos.enum_cons(3).map { |(x1, y1), (x2, y2), (x3, y3)| Math::atan2(y3 - y2, x3 - x2) - Math::atan2(y2 - y1, x2 - x1) }.inject(0.0) { |a, b| a + (b.abs > Math::PI ? 0 : b) } / (mousepos.length-2) $year += angle * 360 / Math::PI / 5 GLUT.PostRedisplay } GLUT.Init GLUT.InitDisplayMode GLUT::DOUBLE | GLUT::RGB GLUT.InitWindowSize 500, 500 GLUT.InitWindowPosition 100, 100 GLUT.CreateWindow $0 GL.ClearColor 0.0, 0.0, 0.0, 0.0 GL.ShadeModel GL::FLAT GLUT.DisplayFunc display GLUT.ReshapeFunc reshape GLUT.MotionFunc motion GLUT.KeyboardFunc keyboard GLUT.MainLoop