How to create advanced splines in ThreeJS? - three.js

I am a designer/typographer that recently started in the world of programming. I am very excited about threeJS and all the possibilities to create great interactive stuff with it.
I want to create a custom spline and extrude a shape on it, like this example: https://www.dropbox.com/s/x1f47i3tmq5icz2/Screenshot%202014-07-06%2020.03.50.png
I've seen that I need to draw the ThreeJS vectors:
var sampleClosedSpline = new THREE.ClosedSplineCurve3([
new THREE.Vector3(0, -40, -40),
new THREE.Vector3(0, 40, -40),
new THREE.Vector3(0, 140, -40),
new THREE.Vector3(0, 40, 40),
new THREE.Vector3(0, -40, 40),
]);
It is a tool to simplify the process? Or I have to make every point by myself?

Figure it out and I want to share it with everybody.
There is a plugin for illustrator named AI2Canvas
after you simplify your design into straight lines (no bezier curves) you can export it and it will give you points like these ones:
ctx.lineTo(36.4, 96.4);
ctx.lineTo(44.0, 84.6);
ctx.lineTo(44.7, 76.4);
ctx.lineTo(44.7, 66.5);
ctx.lineTo(44.7, 46.5);
ctx.lineTo(44.9, 33.0);
ctx.lineTo(48.9, 21.6);
ctx.lineTo(60.8, 14.6);
ctx.lineTo(75.0, 17.3);
ctx.lineTo(83.3, 30.4);
Then by your wisdom of your editor you can make them like these ThreeJS friendly:
new THREE.Vector3(12.2- 100, 98.9),
new THREE.Vector3(36.4- 100, 96.4),
new THREE.Vector3(44.0- 100, 84.6),
new THREE.Vector3(44.7- 100, 76.4),
new THREE.Vector3(44.7- 100, 66.5),
new THREE.Vector3(44.7- 100, 46.5),
new THREE.Vector3(44.9- 100, 33.0),
new THREE.Vector3(48.9- 100, 21.6),
new THREE.Vector3(60.8- 100, 14.6),
new THREE.Vector3(75.0- 100, 17.3),
new THREE.Vector3(83.3- 100, 30.4),
There is no Z axis on these ones, luckily we can have only XY to define a point

Related

How to create a simple three dimensional coordinate display?

I have a series of data that simply represents X/Y/Z coordinates, and would like to display them on screen. I am aware of the existence of three.js, but the examples I have waded through so far seem to be for far more complex animations and whatnot, and have not managed to find an ELI5 tutorial of set of documentation to get me going.
Note that I am not married to three.js, but it does seem like the best tool for the job.
I'm not looking for someone to do it for me, just some links to some basic documentation would be so very appreciated!
Straightforward, conceptually consists of making sphere's and setting their position to your coordinates.
1) Have coordinate data
const coordData = [
{x: 9, y: 2, z: 6},
{x: 3, y: 7, z: 4},
...
]
2) Create Geometry, Material and Group
const pointGeom = new THREE.SphereBufferGeometry( 5, 32, 32 ),
pointMat = new THREE.MeshBasicMaterial({ color: 0xffff00 }),
pointGroup = new THREE.Group();
3) Loop over coordinate data and create a point (sphere) for each using above const's
for (var i = coordData.length - 1; i >= 0; i--) {
const coord = coordData[i],
point = new THREE.Mesh( pointGeom, pointMat );
point.position.set( coord.x, coord.y, coord.z );
pointGroup.add(point);
}
4) Add Group to your scene
scene.add(pointGroup);
I ended up coming up with a great answer through the plot.ly library. This page was pretty much perfect for what I wanted to do.
https://plot.ly/javascript/3d-point-clustering/

Positioning Objects at the same Elevation

I have an issue with the position of cubes in my application. When I set them all with the same size they are rendered properly on the same Y position as I defined:
Example:
geometry = new THREE.BoxGeometry(50, 50, 50);
material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(100, 0, 400); // I always set y as 0 because I want the cubes to be on the same level like buildings in a city
And I do the same for the next cubes, only changing the X and Z positions.
However, when I create cubes with different sizes, which is my objective, as follows,
geometry = new THREE.BoxGeometry(50, 100, 50);
they appear on a different level in the final visualization on the browser, as shows the image:
https://cloud.githubusercontent.com/assets/3678443/8651664/35574c18-2972-11e5-8c75-2612733ea595.png
Any ideas on how to solve this problem? What am I doing wrong?
BoxGeometry is centered on the origin. There are two solutions to translating the box so it sits on the XZ-plane.
Option 1. Translate the geometry so the bottom face of the box passes through the origin. You do that by translating the geometry up by half its height.
geometry = new THREE.BoxGeometry( 50, 50, 50 );
geometry.translate( 0, 50 / 2, 0 );
mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 100, 0, 400 );
Option 2. Translate the mesh by setting its position.
geometry = new THREE.BoxGeometry( 50, 50, 50 );
mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 100, 50 / 2, 400 );
The first option is likely preferable for your use case.
three.js r.92
The Position of the Objects is correct, they are placed where their centerĀ“s are. So your cube with 100 height in geometry extends 50 to the top and 50 to the bottom, its centroid is right in its "middle" at 0.
You could set the y positions of your Cubes to y + cube.geometry.parameters.height / 2 so every cube is aligned at one level (variable y).

using cache in a complex structure

I'm using easeljs to build a certain structure.
Inside that structure, there are many containers and shapes.
I ran across a problem where I needed to change the color of a certain element when the user hovered it with his mouse. I managed to do it However there is a considerable delay until the color is drawn and return to its original color because the stage redraws itself.
I saw that I could use the cache for this purpose so I follow the example in the docs like this:
myShape.cache(150, 150, 100, 100, 1); however nothings happens and I don't see the shape.
I have to say that the shape resides inside a container which is added to the stage.
Here's the relevant code:
enter code here
var g = curShape.graphics.clone().clear();
g.beginFill("#2aa4eb");
g.drawRoundRect(0, 0, curShape.width, curShape.height, 1.5);
//g.drawRect(0, 0, curShape.width + 2, curShape.height + 2);
g.endFill();
g.endStroke();
var newShape= new createjs.Shape(g);
newShape.cache(150, 150, 100, 100, 2);
Any help would be appreciated
You are caching at x:150 and y:150, but you are drawing your shapes at 0,0. If your shape is smaller than 150x150, then it will be caching nothing. Change your cache to 0,0, and it should be fine.
Additionally, you are not providing the 5th parameter (corner radius) to the drawRoundRect call, which will make it fail. Here is a quick sample with a modified version of your code.
http://jsfiddle.net/LNXVg/
var stage = new createjs.Stage("canvas");
var g = new createjs.Graphics();
g.beginFill("#2aa4eb");
g.drawRoundRect(0, 0, 300, 200, 5);
var newShape = new createjs.Shape(g);
//newShape.cache(150, 150, 100, 100, 2);
newShape.cache(0, 0, 100, 100, 2);
stage.addChild(newShape);
stage.update();

Non-radial texture mapping over a ring geometry in WebGL using Three.js

I am trying to simulate image deformation effects using textures over 2D geomtries using the ThreeJS library. I want to apply a texture image over a hollow circle (basically, a ring built by the THREE.RingGeometry function) and obtain the results shown at this image:
Following I show the results I am obtaining in my scene both for the solid ring and its wireframed version:
The problem is that, as you see, the texture is been applied in a radial way, from the center of the ring to the outside. However, what I really need is to apply the texture image on a concentric circle way, as shown in the first image of this question.
The idea is to produce a deformed version of the original texture over a ring shape. I would like to know how this effect can be programmatically achieved through Three.js in such a way that the destination shape can be any arbitrary 2D geometry .
Following, there is the relevant code I am using to draw my scene:
var texture = THREE.ImageUtils.loadTexture('./images/texture.png');
var wireRing = new THREE.Mesh(new THREE.RingGeometry(10, 20, 50, 5, 0, Math.PI * 2), new THREE.MeshBasicMaterial({map: texture, wireframe: true}));
wireRing.position.set(-25, 50, 0);
scene.add(wireRing);
var ring = new THREE.Mesh(new THREE.RingGeometry(10, 20, 50, 5, 0, Math.PI * 2), new THREE.MeshBasicMaterial({map: texture}));
ring.position.set(25, 50, 0);
scene.add(ring);
You just need to change the UV mapping in RingGeometry like so:
uvs.push( new THREE.Vector2( o / thetaSegments, i / phiSegments ) );
Also, if you want to rotate the texture around the ring, you instantiate the RingGeometry by varying the thetaStart parameter:
var geometry = new THREE.RingGeometry( 10, 20, 50, 5, thetaStart, Math.PI * 2 );
three.js r.67

Can geometry be partially hidden by manipulating the far plane of the camera?

I'm attempting to manipulate the camera far plane to hide a portion of a THREE.Line object. However, I must be doing something wrong.
I set the near- and far plane using:
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 2, 0);
Next, I create the geometry:
geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-1, 0, 0));
geometry.vertices.push(new THREE.Vector3(1, 0, 0));
geometry.vertices.push(new THREE.Vector3(1, 0, -2)); // outside far plane
geometry.vertices.push(new THREE.Vector3(0, 0, -3)); // outside far plane
geometry.vertices.push(new THREE.Vector3(-1, 0, -2)); // outside far plane
geometry.vertices.push(new THREE.Vector3(-1, 0, 0));
Finally, I create the line and add it to the scene:
lines = new THREE.Line(geometry, material);
lines.frustumCulled = true; // default?
scene.add(lines);
The entire object is shown in the frustum.
Please see fiddle at http://jsfiddle.net/g52w4/2/
The near and far plane parameters are distances (from the camera). They should be positive, with the far greater than the near.
Set your far plane to 5, for example.
fiddle: http://jsfiddle.net/gpT5K/
three.js r.65

Resources