Space Time (updated!)
My entry is called ‘Space Time‘. A 3D cube clock. The full source code that is readable is below the article.
Wow, it is amazing at what you can you do in 30 lines of JavaFX code or 3000 characters. JFXStudio is running a contest and the theme has to do with “TIME”. Although I posted my entry very last minute, there will be other chances for you to enter. Please visit http://jfxstudio.wordpress.com/2009/08/31/jfxstudio-challenge-small-is-the-new-big/
My entry including the import statements are just at 30 lines with each line containing less than or equal to 100 characters. Click on the image to launch the demo.
Instructions:
import javafx.animation.*;import javafx.scene.*;import javafx.scene.paint.Color;import javafx.scene .effect.*;import javafx.scene.text.*;import javafx.scene.shape.*;import javafx.scene.input. MouseEvent;import javafx.util.Math;class P{var x:Number;var y:Number;var z:Number;var sX:Number;var sY:Number;}class E{var a:Integer;var b:Integer;}var w:Number=800;var h:Number=600;var a:Number=30; var e:Number=30;var vs:P[]=[];function av(x:Integer,y:Integer,z:Integer){insert P{x:x,y:y,z:z}into vs;}av(-1,-1,-1);av(-1,-1,1);av(-1,1,-1);av(-1,1,1);av(1,-1,-1);av(1,-1,1);av(1,1,-1);av(1,1,1);var es:E[]=[];function aE(a:Integer,b:Integer){insert E{a:a,b:b}into es;}aE(0,1);aE(0,2);aE(0,4);aE(1,3 );aE(1,5);aE(2,3);aE(2,6);aE(3,7);aE(4,5);aE(4,6);aE(5,7);aE(6,7);var ps:Circle[]=[];var ls:Line[]= [];function mps(c:Boolean):Void{var th:Number=bind 0.017453*a;var ph=0.017453*e;var cT=Math.cos(th) ;var sT=Math.sin(th);var cP=Math.cos(ph);var sP=Math.sin(ph);var cTcP=cT*cP;var cTsP=cT*sP;var sTcP =sT*cP;var sTsP=sT*sP;var sf=bind w/4;for(i in[0..sizeof vs-1]){var x0=vs[i].x;var y0=vs[i].y;var z0=vs[i].z;var x1=cT*x0+sT*z0;var y1=-sTsP*x0+cP*y0+cTsP*z0;var z1=cTcP*z0-sTcP*x0-sP*y0;x1=x1*3/( z1+4.5);y1=y1*3/(z1+4.5);vs[i].sX=x1;vs[i].sY=y1;if(c)insert Circle{centerX:bind w/2+sf*vs[i].sX+.5 ,centerY: bind h/2-sf*vs[i].sY+.5,radius:2 fill:Color.BLUE}into ps;}if(c)for(e in es){insert Line{ startX:bind ps[e.a].centerX startY:bind ps[e.a].centerY endX:bind ps[e.b].centerX endY:bind ps[e.b] .centerY strokeWidth:2,stroke:Color.BLUE}into ls;}}mps(true);var mx:Number;var my:Number;var g: Rectangle=Rectangle{x:0,y:0 width:bind w,height:bind h fill:Color.BLACK onMousePressed:function(me: MouseEvent):Void{mx=me.x;my=me.y;}onMouseDragged:function(me:MouseEvent):Void{var new_mx=me.x;a-= new_mx-mx;var new_my=me.y;e+=new_my-my;mx=new_mx;my=new_my;mps(false);}}var ct:String=new java.util .Date().toString();var tz:Integer=-125;var t=Group{content:[Text{effect:Lighting{light:javafx.scene .effect.light.DistantLight{azimuth:bind tz elevation:40}surfaceScale:5} x:10 y:50 content:"Space " "Time" fill:Color.RED font:Font{name:"Arial Bold" letterSpacing:0.20 size:50}},Text{x:10 y:80 content:bind ct fill:Color.BLUE font:Font{name:"Arial Bold" letterSpacing:0.20 size:20}}]}var bc= Group{content:[Rectangle{x:10,y:bind h-85,arcHeight:5,arcWidth:5,width:bind w-30,height:30,fill: Color.RED,opacity:.5},Text{effect:DropShadow{offsetX:10,offsetY:10,color:Color.BLACK,radius:10} opacity:.5 x:15,y:bind h-65,content:"by Carl Dea - carlfx.wordpress.com"fill:Color.WHITE font:Font{ name:"Arial Bold"letterSpacing:.20 size:20}}]}var scene:Scene=Scene{content:bind[g,ps,ls,t,bc]};var anim=Timeline{keyFrames:[KeyFrame{time:1s action:function():Void{a-=1;mps(false);ct=new java.util. Date().toString();if(tz>125){tz=-125;}tz+=2;}}]repeatCount:Timeline.INDEFINITE};anim.play();javafx. stage.Stage{width:bind w with inverse height:bind h with inverse scene:scene}
Enjoy!
Please vote for me…
Let me know what you think. 🙂
Here is the readable source code below:
/** * Main.fx * * Check out http://www.comp.brad.ac.uk/research/GIP/tutorials/project1.html * for all the math. * Created on Dec 20, 2009, 11:06:15 PM */ package bigsmall.part8; import javafx.animation.*; import javafx.scene.*; import javafx.scene.paint.Color; import javafx.scene.effect.*; import javafx.scene.effect.light.DistantLight; import javafx.scene.text.*; import javafx.scene.shape.*; import javafx.scene.input.MouseEvent; import javafx.stage.*; import java.util.Date; import javafx.util.Math; class Point3D { var x: Number; var y: Number; var z: Number; var screenX: Number; var screenY: Number; } class Edge { var a: Integer; var b: Integer; } var width: Number = 800; var height: Number = 600; var azimuth: Number = 30; var elevation: Number = 30; var vertices: Point3D[] = []; function addVertex(x: Integer, y: Integer, z: Integer) { insert Point3D { x: x, y: y, z: z } into vertices; } addVertex(-1, -1, -1); addVertex(-1, -1, 1); addVertex(-1, 1, -1); addVertex(-1, 1, 1); addVertex(1, -1, -1); addVertex(1, -1, 1); addVertex(1, 1, -1); addVertex(1, 1, 1); var edges: Edge[] = []; function addEdge(a: Integer, b: Integer) { insert Edge { a: a, b: b } into edges; } addEdge(0, 1); addEdge(0, 2); addEdge(0, 4); addEdge(1, 3); addEdge(1, 5); addEdge(2, 3); addEdge(2, 6); addEdge(3, 7); addEdge(4, 5); addEdge(4, 6); addEdge(5, 7); addEdge(6, 7); var points: Circle[] = []; var lines: Line[] = []; function movePoints(createFirstTime: Boolean): Void { var theta: Number = bind 0.017453 * azimuth; var phi = 0.017453 * elevation; var cosTheta = Math.cos(theta); var sinTheta = Math.sin(theta); var cosPhi = Math.cos(phi); var sinPhi = Math.sin(phi); var cosThetaCosPhi = cosTheta * cosPhi; var cosThetaSinPhi = cosTheta * sinPhi; var sinThetaCosPhi = sinTheta * cosPhi; var sinThetaSinPhi = sinTheta * sinPhi; var scaleFactor = bind width / 4; for (i in [0..sizeof vertices - 1]) { var x0 = vertices[i].x; var y0 = vertices[i].y; var z0 = vertices[i].z; var x1 = cosTheta * x0 + sinTheta * z0; var y1 = -sinThetaSinPhi * x0 + cosPhi * y0 + cosThetaSinPhi * z0; var z1 = cosThetaCosPhi * z0 - sinThetaCosPhi * x0 - sinPhi * y0; x1 = x1 * 3 / (z1 + 4.5); y1 = y1 * 3 / (z1 + 4.5); vertices[i].screenX = x1; vertices[i].screenY = y1; if (createFirstTime) { insert Circle { centerX: bind width / 2 + scaleFactor * vertices[i].screenX + 0.5, centerY: bind height / 2 - scaleFactor * vertices[i].screenY + 0.5, radius: 2 fill: Color.BLUE } into points; } } if (createFirstTime) { for (edge in edges) { insert Line { startX: bind points[edge.a].centerX startY: bind points[edge.a].centerY endX: bind points[edge.b].centerX endY: bind points[edge.b].centerY strokeWidth: 2, stroke: Color.BLUE } into lines; } } } // create the first time; draw cube. movePoints(true); var mouseX: Number; var mouseY: Number; // Space region that changes the azimuth and recalculates the cube var galaxy: Rectangle = Rectangle { x: 0, y: 0 width: bind width, height: bind height fill: Color.BLACK onMousePressed: function (me: MouseEvent): Void { mouseX = me.x; mouseY = me.y; } onMouseDragged: function (me: MouseEvent): Void { var new_mx = me.x; azimuth -= new_mx - mouseX; var new_my = me.y; elevation += new_my - mouseY; mouseX = new_mx; mouseY = new_my; movePoints(false); } } // galaxy var currentTime: String = new Date().toString(); var initialAzimuth: Integer = -125; // Title with current time seconds. var titleDisplay = Group { content: [ Text { effect: Lighting { light: DistantLight { azimuth: bind initialAzimuth elevation: 40 } surfaceScale: 5 } x: 10 y: 50 content: "Space Time" fill: Color.RED font: Font { name: "Arial Bold" letterSpacing: 0.20 size: 50 } }, Text { x: 10 y: 80 content: bind currentTime fill: Color.BLUE font: Font { name: "Arial Bold" letterSpacing: 0.20 size: 20 } } ] }; // titleDisplay Group // This is the bottom display credits var byCarl = Group { content: [ Rectangle { x: 10, y: bind height - 85, arcHeight: 5, arcWidth: 5, width: bind width - 30, height: 30, fill: Color.RED, opacity: .5 }, Text { effect: DropShadow { offsetX: 10, offsetY: 10, color: Color.BLACK, radius: 10 } opacity: .5 x: 15, y: bind height - 65, content: "by Carl Dea - carlfx.wordpress.com" fill: Color.WHITE font: Font { name: "Arial Bold" letterSpacing: .20 size: 20 } } ] // byCarl contents Group }; // by Carl var scene: Scene = Scene { content: bind [ galaxy, points, lines, titleDisplay, byCarl] }; // this is the ticking motion of the cube. var anim = Timeline { keyFrames: [ KeyFrame { time: 1s action: function (): Void { azimuth -= 1; movePoints(false); currentTime = new Date().toString(); if (initialAzimuth > 125) { initialAzimuth = -125; } initialAzimuth += 2; } } ] // keyFrames repeatCount: Timeline.INDEFINITE }; // animation anim.play(); Stage { title: "Space Time" width: bind width with inverse height: bind height with inverse scene: scene }