Open Jones-S opened 7 years ago
If anyone would like to have a look into the code:
$(function() { // Shorthand for $( document ).ready()
var MIN_DISTANCE = 0.15,
LINE_THICKNESS = 0.012;
var renderer = new THREE.WebGLRenderer({ antialias: true }),
scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 500),
resolution = new THREE.Vector2( window.innerWidth, window.innerHeight ),
animating = false,
line = null,
tubeMesh = null,
cube = null;
var material = new THREE.LineBasicMaterial({
color: 0xffffff,
linewidth: 5
});
var graph = new THREE.Object3D();
scene.add( graph );
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
function run() {
// Render the scene
renderer.render(scene, camera);
// Spin the cube for next frame
if (animating) {
// line.rotation.y -= 0.03;
tubeMesh.rotation.y -= 0.01;
}
// Ask for another frame
requestAnimationFrame(run);
}
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function generateRandomCoordinate() {
// generate random number and round to nearest 0.05
var new_coord = (Math.ceil(Math.random() * (1 / MIN_DISTANCE)) / (1 / MIN_DISTANCE)).toFixed(2);
new_coord = parseFloat(new_coord);
return new_coord;
}
function generateConst(direction) {
var const_coord = randomIntFromInterval(0, 2);
// also check if it is different coordinate than last time
while (const_coord == direction){
const_coord = randomIntFromInterval(0, 2);
}
return const_coord;
}
// Create the Three.js renderer, add it to our div
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.set(0, 1.5, -2);
camera.lookAt(new THREE.Vector3(0, 0.9, 0));
// draw outline cube
// var cube_geometry = new THREE.BoxGeometry(1, 1, 1, 0, 0, 0);
// var cube_material = new THREE.MeshBasicMaterial({color: 0xF0FF91, wireframe: false, transparent: true, opacity: 0.2});
// cube = new THREE.Mesh(cube_geometry, cube_material);
// cube.position.set(-0.5, -0.5, -0.5);
// scene.add(cube);
function generateLineVertices(argument) {
var dir_next_prev = 0,
raycaster,
// generate starting vector (between (0,0,0) and (1,1,1) )
pos_x = generateRandomCoordinate(),
pos_y = generateRandomCoordinate(),
pos_z = generateRandomCoordinate(),
random_steps = randomIntFromInterval(7, 15),
counter = 0,
direction = 0,
directions = [],
// generate randomly which coordinate (x,y,z) should be changed, returns 0, 1 or 2
const_coordinate = 0,
vector_start = new THREE.Vector3(pos_x, pos_y, pos_z),
vector_prev = vector_start,
vector_next,
vertices = [];
// add first vertex
vertices.push(vector_start);
for (var i = 0; i < random_steps; i++) {
direction = const_coordinate; // determines if x/y/z should be changed
directions[i] = direction; // saves the last direction-change
switch(const_coordinate) {
case 0: // change only x
vector_next = new THREE.Vector3(generateRandomCoordinate(), vector_prev.y, vector_prev.z);
break;
case 1: // change only y
vector_next = new THREE.Vector3(vector_prev.x, generateRandomCoordinate(), vector_prev.z);
break;
case 2: // change only z
vector_next = new THREE.Vector3(vector_prev.x, vector_prev.y, generateRandomCoordinate());
break;
default:
}
// direction between last vector and the vector to test
// generate Three Vector from last vertex and vector_next
dir_next_prev = new THREE.Vector3().subVectors(vertices[vertices.length - 1], vector_next);
// normalize vector
dir_next_prev = dir_next_prev.normalize();
// a raycaster will check if the new vector could cross another line
// generate a Raycaster with the direction from above and with the new vector to check
raycaster = new THREE.Raycaster(vector_next, dir_next_prev);
raycaster.linePrecision = 2;
var geometry_next_prev;
var flag_found_intersection = false;
// check if new point is on line between to others
for (var j = 0; j < vertices.length; j++) {
if (j >= 1) {
var vA = vertices[j - 1];
var vB = vertices[j];
// // get direction between the two points
// var dir_B_A = new THREE.Vector3().subVectors(vA, vB);
// console.log("dir_B_A: ", dir_B_A);
// // move point A into the direction dir_B_A
// dir_B_A.setLength(MIN_DISTANCE/2);
// console.log("dir_B_A: ", dir_B_A);
geometry_next_prev = new THREE.Geometry();
// make a new geometry with the two points to evaluate
geometry_next_prev.vertices.push(vA, vB);
var test_line = new THREE.Line(geometry_next_prev, new THREE.LineBasicMaterial({ color: 0x0000ff }));
// testing the raycaster against the test line
var intersection = raycaster.intersectObject(test_line);
// console.log("intersection: ", intersection);
if (intersection.length > 0) {
flag_found_intersection = true;
}
}
}
if ((flag_found_intersection === true || vector_prev == vector_next)) {
if (vector_prev == vector_next) {
// console.log("%c length was 0", "background: #FD3FB7; color: #DA5C1B");
}
if (counter < 15) {
i--;
counter++;
continue;
} else if (counter >= 15 && counter < 25) {
} else {
// console.log("%c counter up - - - - - - - - - - - - - - - -", "background: #FD5B0F; color: #DA5C1B");
// console.log("%c vertices", "background: #0D0B07; color: #FAFBFF", vertices);
counter = 0;
break;
}
}
counter = 0;
const_coordinate = generateConst(direction);
// console.log("%c vector_next", "background: #0D0B07; color: #FAFBFF", vector_next);
// add new vector to geometry
vertices.push(vector_next);
// set prev vector
vector_prev = vector_next;
}
// console.log("directions: ", directions);
return vertices;
}
function generateMesh() {
var lineVertices = generateLineVertices();
// console.log("%c lineVertices", "background: #0D0B07; color: #FAFBFF", lineVertices);
var meshMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
// meshMaterial.color.setHSL(0, 0.8, 0.5);
var tube_line_geometry = new THREE.Geometry();
tube_line_geometry.vertices = lineVertices;
var line = new THREE.MeshLine();
line.setGeometry( tube_line_geometry );
var material = new THREE.MeshLineMaterial({
color: new THREE.Color( 0xffffff ),
useMap: false,
opacity: 0.5,
taper: 'linear',
resolution: resolution,
sizeAttenuation: false,
lineWidth: 30,
near: camera.near,
far: camera.far
});
tubeMesh = new THREE.Mesh( line.geometry, material ); // this syntax could definitely be improved!
graph.add( tubeMesh );
}
generateMesh();
$('body').keydown(function( event ) {
if ( event.which != 38 ) {
return;
}
scene.remove(tubeMesh);
// scene.remove(line);
generateMesh();
});
// Add a mouse up handler to toggle the animation
$(window).mouseup(function() {
// console.log("mouse changed");
animating = !animating;
});
// Run our render loop
run();
});
}(jQuery));
Thanks in advance!
I'm facing a same issue. How did you solve this, if you did?
I did. I only vaguely remember: I just added a sphere at the end of the tube to imitate a round corner effect...
Hey there I actually wrote the stackoverflow question mentioned in the other issue:
19
I tried to get a result like the on in the picture of the post with your MeshLine.js, but What I currently get is something like this:
I disabled sizeAttenuation but it would still make this strange thickenings of the lines. Is it maybe because my meshLine has different vertices and I am not creating one line for each segment, like you did it in your graph-example? (https://www.clicktorelease.com/code/THREE.MeshLine/demo/graph.html)
Or do you have any other hints on how I could get such a shape with rounded corners, which looks tube-like?
I would be very thankful for any help here. :v: Cheers