Skip to content

Instantly share code, notes, and snippets.

@aemkei
Forked from 140bytes/LICENSE.txt
Created August 5, 2011 10:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aemkei/1127274 to your computer and use it in GitHub Desktop.
Save aemkei/1127274 to your computer and use it in GitHub Desktop.
rotate3D - 140byt.es

rotate3D - 140byt.es

A simple 3D "library" in 140 bytes of JavaScript.

See the demo page: http://jsfiddle.net/aemkei/cPa3T/show/

Usage

rotate3D(
  pointX, pointY, pointZ, 
  rotationX, rotationY, 
  focalLength
);

// returns new coords: 
{ x: newX, y: newY, z: newZ }

Author

Created by Martin Kleppe (@aemkei) at Ubilabs.

For more information

See the 140byt.es site for a showcase of entries (built itself using 140-byte entries!), and follow @140bytes on Twitter.

To learn about byte-saving hacks for your own code, or to contribute what you've learned, head to the wiki.

140byt.es is brought to you by Jed Schmidt, with help from Alex Kloss. It was inspired by work from Thomas Fuchs and Dustin Diaz.

// pass x,y,z coords, the rotation and the camera focal length
function rotate3D(
pointX, pointY, pointZ,
rotationX, rotationY,
focalLength
){
var sin = Math.sin,
cos = Math.cos,
xz = sin(rotationX) * pointY + cos(rotationX) * pointZ,
yz = cos(rotationY) * xz - sin(rotationY) * pointX,
scale = (focalLength / (focalLength + yz));
// returns the new coords as an object
return {
x: sin(rotationY) * xz + cos(rotationY) * pointX * scale,
y: (cos(rotationX) * pointY - sin(rotationX) * pointZ) * scale,
z: yz
};
}
function(a,b,c,d,e,f){var g=Math.sin,h=Math.cos,i=g(d)*b+h(d)*c,j=h(e)*i-g(e)*a,k=f/(f+j);return{x:g(e)*i+h(e)*a*k,y:(h(d)*b-g(d)*c)*k,z:j}}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "rotate3D",
"description": "A 3D rotation method. Simply pass a point, rotation (X,Y) and focal length.",
"keywords": [
"3d",
"rotate"
]
}
<!DOCTYPE html>
<head>
<title>rotate3D - 140bytes</title>
<style type="text/css">
body { background-color: #000; overflow: hidden; }
#stage { width: 1px; height: 1px; margin: 200px auto 0; position: relative; }
a { display: block; text-align: center; color: #FFF; }
#stage div { background: #FFF; width: 4px; height: 4px; position: absolute; }
</style>
</head>
<body>
<a href="https://gist.github.com/1127274">View Source</a>
<div id="stage"></div>
<script>
function rotate3D(a,b,c,d,e,f){var g=Math.sin,h=Math.cos,i=g(d)*b+h(d)*c,j=h(e)*i-g(e)*a,k=f/(f+j);return{x:g(e)*i+h(e)*a*k,y:(h(d)*b-g(d)*c)*k,z:j}};
var points = [],
elems = [],
rotateX = 0,
rotateY = 0;
function createCube(){
var x, y, z;
for (x=-1; x<2; x++){
for (y=-1; y<2; y++){
for (z=-1; z<2; z++){
points.push({
x: x * 100,
y: y * 100,
z: z*100
});
}
}
}
}
function setup(){
var stage = document.getElementById("stage"),
elem, i, point;
for (i=0; point=points[i]; i++){
elem = document.createElement("div");
stage.appendChild(elem);
elems.push(elem);
}
}
function render(){
var i, point, coords, size;
rotateX += 0.03;
rotateY += 0.07;
for (i=0; point=points[i]; i++){
coords = rotate3D(point.x, point.y, point.z, rotateX, rotateY, 500);
elem = elems[i];
size = (200-coords.z) / 20;
elem.style.top = coords.y + "px";
elem.style.left = coords.x + "px";
elem.style.width = size + "px";
elem.style.height = size + "px";
elem.style.opacity = size/20;
}
setTimeout(render, 40);
}
createCube();
setup();
render();
</script>
</body>
@atk
Copy link

atk commented Aug 6, 2011

One word: awesome!

@plu
Copy link

plu commented Sep 3, 2011

aemkei++

@JavaScript-Packer
Copy link

Thanks! Using a 846 byte minified version (837 bytes without line breaks) of full HTML demo (1,498 bytes test.html) that centers top of screen and goes 9 layers behind fixed position. I can still see a few bytes I could shave off, but I don't feel like being that picky right now...

<style>#cube{width:1px;height:1px;margin:200px auto 0;position:fixed;top:-170px;left:50%}
#cube div{background:red;width:4px;height:4px;position:absolute;z-index:-9}</style>
<div id="cube"></div><script>function e(e,t,o,r,n,l){var a=Math.sin,s=Math.cos,i=a(r)*t+s(r)*o,
p=s(n)*i-a(n)*e,m=l/(l+p);return{x:a(n)*i+s(n)*e*m,y:(s(r)*t-a(r)*o)*m,z:p}}function t(e,t,o){
for(e=-1;2>e;e++)for(t=-1;2>t;t++)for(o=-1;2>o;o++)n.push({
x:88*e,y:88*t,z:88*o})}function o(e,t,o,r,d){d=document;r=d.getElementById("cube");
for(t=0;o=n[t];t++)e=d.createElement("div"),r.appendChild(e),l.push(e)}
function r(t,o,i,p,S){S='style';for(a+=.03,s+=.07,t=0;o=n[t];t++)i=e(o.x,o.y,o.z,a,s,500),
z=l[t],p=(200-i.z)/20,z[S].top=i.y+"px",z[S].left=i.x+"px",z[S].width=p+"px",
z[S].height=p+"px",z[S].opacity=p/20;setTimeout(r,50)}var n=[],l=[],a=0,s=0;t(),o(),r()</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment