Skip to content

Instantly share code, notes, and snippets.

@kohske
Created February 4, 2012 12:40
Show Gist options
  • Save kohske/1737618 to your computer and use it in GitHub Desktop.
Save kohske/1737618 to your computer and use it in GitHub Desktop.
r3js
source('r3js.r')
obj <- r3js_new()
N <- 250
x <- rnorm(N, 0.5, 0.2)
y <- rnorm(N, 0.5, 0.2)
z <- rnorm(N, 0.5, 0.2)
obj <- r3js_add(obj, r3js_point(x, y, z))
y <- seq(0, 1, 0.005)
x <- cos(y*50) / 2 + 0.5
z <- sin(y*50) / 2 + 0.5
obj <- r3js_add(obj, r3js_line(x, y, z))
r3js_gen(obj)
<!doctype html>
<html lang="en">
<head>
<title>r3js</title>
<meta charset="utf-8">
</head>
<body>
<div id="info">
<script src="Three.js"></script>
<script>
%data%
</script>
<script>
%js%
</script>
</body>
</html>
var container;
var camera, scene, renderer, particles, geometry, materials = [], parameters, i, h, color;
var pointLight;
var mousedown = false;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var onMouseDownPosition, radious = 3, theta = 0, onMouseDownTheta = 0, phi = 0, onMouseDownPhi = 0;
init();
render()
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 3000 );
camera.position.x = radious * Math.sin( theta * Math.PI / 360 ) * Math.cos( phi * Math.PI / 360 );
camera.position.y = radious * Math.sin( phi * Math.PI / 360 );
camera.position.z = radious * Math.cos( theta * Math.PI / 360 ) * Math.cos( phi * Math.PI / 360 );
camera.target = new THREE.Vector3(0, 0, 0);
camera.lookAt(camera.target);
camera.updateMatrix();
scene.add( camera );
// axis
var axisx = new THREE.Geometry();
axisx.vertices.push( new THREE.Vertex( new THREE.Vector3(-1,0,0)));
axisx.vertices.push( new THREE.Vertex( new THREE.Vector3(1,0,0)));
scene.add(new THREE.Line( axisx, new THREE.LineBasicMaterial( { color: 0xff0000, opacity: 1, linewidth: 5} )));
var axisy = new THREE.Geometry();
axisy.vertices.push( new THREE.Vertex( new THREE.Vector3(0,-1,0)));
axisy.vertices.push( new THREE.Vertex( new THREE.Vector3(0,1,0)));
scene.add(new THREE.Line( axisy, new THREE.LineBasicMaterial( { color: 0x00ff00, opacity: 1, linewidth: 5} )));
var axisz = new THREE.Geometry();
axisz.vertices.push( new THREE.Vertex( new THREE.Vector3(0,0,-1)));
axisz.vertices.push( new THREE.Vertex( new THREE.Vector3(0,0,1)));
scene.add(new THREE.Line( axisz, new THREE.LineBasicMaterial( { color: 0x0000ff, opacity: 1, linewidth: 5} )));
// light
pointLight = new THREE.PointLight( 0xFFFFFF );
pointLight.position = new THREE.Vector3(3, 3, 3);
scene.add(pointLight);
pointLight = new THREE.PointLight( 0xFFFFFF );
pointLight.position = new THREE.Vector3(-3, -3, -3);
scene.add(pointLight);
// mouse
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mouseup', function(e){mousedown = false;}, false );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
onMouseDownPosition = new THREE.Vector2();
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
// data
var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x0044FF});
var radius = 0.02, segments = 16, rings = 16;
for (var i = 0; i < r3jsdata.values.length; ++i) {
var p = r3jsdata.values[i];
switch(p.type) {
case "point":
for ( var j = 0; j < p.n; j ++ ) {
var sphere = new THREE.Mesh(new THREE.SphereGeometry(radius, segments, rings), sphereMaterial);
sphere.position = new THREE.Vector3(p.x[j], p.y[j], p.z[j]);
scene.add(sphere);
}
break;
case "line":
line = new THREE.Geometry();
for ( var j = 0; j < p.n; j ++ ) {
line.vertices.push(new THREE.Vertex( new THREE.Vector3(p.x[j], p.y[j], p.z[j])));
}
scene.add(new THREE.Line( line, new THREE.LineBasicMaterial( { color: 0x888800, opacity: 1, linewidth: 2} )));
break;
}
}
}
function onDocumentMouseDown( event ) {
event.preventDefault();
onMouseDownTheta = theta;
onMouseDownPhi = phi;
onMouseDownPosition.x = event.clientX;
onMouseDownPosition.y = event.clientY;
mousedown = true;
}
function onDocumentMouseMove( event ) {
event.preventDefault();
if ( mousedown ) {
theta = - ( ( event.clientX - onMouseDownPosition.x ) * 0.5 ) + onMouseDownTheta;
phi = ( ( event.clientY - onMouseDownPosition.y ) * 0.5 ) + onMouseDownPhi;
camera.position.x = radious * Math.sin( theta * Math.PI / 360 ) * Math.cos( phi * Math.PI / 360 );
camera.position.y = radious * Math.sin( phi * Math.PI / 360 );
camera.position.z = radious * Math.cos( theta * Math.PI / 360 ) * Math.cos( phi * Math.PI / 360 );
camera.lookAt(camera.target);
camera.updateMatrix();
pointLight.position.x = camera.position.x;
pointLight.position.y = camera.position.y + 3;
pointLight.position.z = camera.position.z;
render();
}
}
function render() {
renderer.render( scene, camera );
}
library(rjson)
r3js_point <- function(x, y, z) {
list(type = "point", n = length(x), x = x, y = y, z = z)
}
r3js_line <- function(x, y, z) {
list(type = "line", n = length(x), x = x, y = y, z = z)
}
r3js_tojson <- function(obj) {
sprintf("var r3jsdata = %s;", toJSON(obj))
}
r3js_add <- function(obj, value) {
obj$values <- c(obj$values, list(value))
obj
}
r3js_new <- function(xlim = c(0, 1), ylim = c(0, 1), zlim = c(0, 1), values = NULL) {
list(xlim = xlim, ylim = ylim, values = values)
}
r3js_gen <- function(obj, name = "r3js", dir = tempdir(), browse = TRUE) {
dir.create(dir)
file.copy("Three.js", dir, TRUE)
file.copy("LICENSE.Three.js", dir, TRUE)
sf <- file("r3js.html", "r")
src <- readLines(sf)
close(sf)
jf <- file("r3js.js", "r")
js <- readLines(jf)
close(jf)
src <- sub("%data%", paste(r3js_tojson(obj), collapse = "\n"), src)
src <- sub("%js%", paste(js, collapse = "\n"), src)
ofp <- sprintf("%s/%s.html", dir, name)
of <- file(ofp, "w")
writeLines(src, of)
close(of)
if (browse) browseURL(paste("file:///", normalizePath(ofp), sep = ""))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment