How to plot 3D Graph in XYZ axis jquery - javascript

I am trying to plot a graph in my application. I am trying to plot a graph having 4 points which needs to be joined by lines. I tried with so many libralies such as canvasXpress.. But could not able to find the solution.
I had tried this much.
http://jsfiddle.net/rohitghatol/tn9sm/
var render = function(){
renderer.render(scene,camera);
}
render();
$("#container").append(renderer.domElement);
Now I have to draw 4 points with joining lines.
I am not getting how to scale and plot the lines in the graph.

I have found the solution using Three.Js javascript library. Here's the snippet.
I had used the following code to create the grid helpers and it worked.
var gridXZ = new THREE.GridHelper(100, 10);
gridXZ.setColors(new THREE.Color(0x939393), new THREE.Color(0xbdbdbd));
gridXZ.position.set(100, -.1, 100);
scene.add(gridXZ);
var gridXY = new THREE.GridHelper(100, 10);
gridXY.position.set(100, 100, 0);
gridXY.rotation.x = Math.PI / 2;
gridXY.setColors(new THREE.Color(0x0066FF), new THREE.Color(0xCCE0F9));
scene.add(gridXY);
var gridYZ = new THREE.GridHelper(100, 10);
gridYZ.position.set(0, 100, 100);
gridYZ.rotation.z = Math.PI / 2;
gridYZ.setColors(new THREE.Color(0xCC9900), new THREE.Color(0xF5EBCC));
scene.add(gridYZ);
And for drawing the lines I had drawn the lines using three D points
// Line one
material = new THREE.LineBasicMaterial({
color: 0x000000
});
geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3(x1, y1, z1),
new THREE.Vector3(x2, y2, z2)
);
line = new THREE.Line(geometry, material);
scene.add(line);

Related

three.js Line disappears on updating the vertices of its geometry

I am learning three.js library in JS. I used the Line objects to create my own coordinate axes. I am trying to move them. The problem is when I update the vertices, two of the lines work fine, but the third line disappears completely. I tried printing its vertices on console but they are within visibility range. So, what is the reason I am facing this problem? My code:
// create and axes to the scene
//// X axis
var material = new THREE.LineBasicMaterial({
color: 0x00ff00
})
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(1500,0,0), new THREE.Vector3(-1500,0,0));
Xaxis = new THREE.Line(geometry,material);
scene.add(Xaxis);
//// Y axis
var material = new THREE.LineBasicMaterial({
color: 0xff0000
})
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0,1500,0), new THREE.Vector3(0,-1500,0));
Yaxis = new THREE.Line(geometry,material);
scene.add(Yaxis);
//// Z axis
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
})
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0,0,1500), new THREE.Vector3(0,0,-1500));
Zaxis = new THREE.Line(geometry,material);
scene.add(Zaxis);
function changePosition(newVal)
{
if(!transformCo_ordinate) {
sphere.position.set((vx/100)*newVal,(vy/100)*newVal,(vz/100)*newVal);
}
else{
Xaxis.geometry.vertices[0].set(1500,-(vy/100)*newVal,-(vz/100)*newVal);
Xaxis.geometry.vertices[1].set(-1500,-(vy/100)*newVal,-(vz/100)*newVal);
Yaxis.geometry.vertices[0].set(-(vx/100)*newVal,1500,-(vz/100)*newVal);
Yaxis.geometry.vertices[1].set(-(vx/100)*newVal,-1500,-(vz/100)*newVal);
Zaxis.geometry.vertices[0].set(-(vx/100)*newVal,-(vy/100)*newVal,1500);
Zaxis.geometry.vertices[0].set(-(vx/100)*newVal,-(vy/100)*newVal,-1500);
Xaxis.geometry.verticesNeedUpdate = true;
Yaxis.geometry.verticesNeedUpdate = true;
Zaxis.geometry.verticesNeedUpdate = true;
console.log(Xaxis.geometry.vertices[1]);
}
}
THe function changePosition is being called by a slider which passes its current value as newVal within range 0-100. vx = 100, vy = 100, vz = -300
Xaxis is the line that disappears. transformCo_ordinate is a boolean controlled by a checkbox. I am new to three.js so please understand if I am doing some stupid mistake.
Zaxis.geometry.vertices[0].set(-(vx/100)*newVal,-(vy/100)*newVal,1500);
Zaxis.geometry.vertices[0].set(-(vx/100)*newVal,-(vy/100)*newVal,-1500);
It seems you are updating the same vertex of the z axis twice. I've ported a simplified version of your code into the following fiddle. After fixing this minor bug, everything seems to work fine.
https://jsfiddle.net/gcL7dwbp/
The axis are automatically updated two seconds after application start.
three.js R104

How to animate the growth of a line in Three.js?

What I have:
var pointA = new THREE.Vector3(camera_RC_Holder.position.x, camera_RC_Holder.position.y, camera_RC_Holder.position.z);
var direction = camera_RC.position.clone();
direction.applyMatrix4( camera_RC.matrixWorld );
direction.normalize();
var distance = 700;
var pointB = new THREE.Vector3();
pointB.addVectors ( pointA, direction.multiplyScalar( -distance ) );
var geometry = new THREE.Geometry();
geometry.vertices.push( pointA );
geometry.vertices.push( pointB );
var material = new THREE.LineBasicMaterial( { color : 0xff0000 } );
var line = new THREE.Line( geometry, material );
scene_Main.add( line );
What I want:
What I'm trying to do is to show that a ray has began from the camera and explores through the view volume. So, instead of instantly create a line (point_A, point_B) I want to grow the line from point_A pixel by pixel until it meets it's destination (point_B).
Question:
How to draw the lines pixel by pixel as shown in the code snippet below??
var w = 200;
var h = 150;
var x;
function setup(){
createCanvas(w,h);
x=0;
y=0;
}
function draw(){
if(x>w){
x = 0;
}
background(250);
line(0,50,x,50); //x1,y1,x2,y2
x++;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
Title question and explanation does not fit to me very well, maybe I did not understand your question perfectly. I will try to answer just the title question and edit this answer as soon as some clarifications are done from your side.
( Also I would always try to avoid multi-questions as much as possible. )
About the title question:
Adding something to the scene is basically drawing it... or do you mean something else?
Bind this code snippet to your click mouse event. This will create your raycast, in order to see it you need to add it to your scene. Afterwards you can move your camera and check how it looks like:
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(raycaster.ray.origin.x, raycaster.ray.origin.y, raycaster.ray.origin.z));
geometry.vertices.push(new THREE.Vector3(raycaster.ray.origin.x + (raycaster.ray.direction.x * 100000), raycaster.ray.origin.y + (raycaster.ray.direction.y * 100000), raycaster.ray.origin.z + (raycaster.ray.direction.z * 100000)));
var line = new THREE.Line(geometry, material);

Threejs draw a path with textures

I want to draw a path in my 3D world, but the class of line is not useful. Who can help me?!
Like this image
Now I fixed my question
I want draw a path ,and fill it with texture
var SUBDIVISIONS = 20;
geometry = new THREE.Geometry();
var curve = new THREE.QuadraticBezierCurve3();
curve.v0 = new THREE.Vector3(0, 0, 110);
curve.v1 = new THREE.Vector3(0, 200, 110);
curve.v2 = new THREE.Vector3(200, 200, 110);
for (j = 0; j < SUBDIVISIONS; j++) {
geometry.vertices.push( curve.getPoint(j / SUBDIVISIONS) )
}
material = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 5 } );
line = new THREE.Line(geometry, material);
scene.add(line);
this way has two problem 1:linewidth is not support on Windows ,2: LineBasicMaterial not support texture
So i search on google find class Three.MeshLine. linewidth is Ok,but texture mapping not fine. texture code there:var loader = new THREE.TextureLoader();
loader.load( 'assets/images.png', function( texture ) {
strokeTexture = texture;
strokeTexture.wrapS = strokeTexture.wrapT = THREE.RepeatWrapping;
strokeTexture.repeat.set( 5, 1);
strokeTexture.needsUpdate = true;
init()
} );
Regardless of the setting the texture and MeshLineMaterial ,The result is not what I want result image:result image
have a look at https://github.com/spite/THREE.MeshLine - it's an implementation of mesh-based lines. Also note the references on that site, could give you some insights.
Otherwise you might want to look into creating a shape from the line. This could be done using the THREE.ShapeGeometry-class.

Drawing a Line3 in Threejs

I want to draw a Line3 in a Threejs and here is my code for it:
start = new THREE.Vector3(20, 10, 0);
end = new THREE.Vector3(200, 100, 0);
var line = new THREE.Line3(start, end);
scene.add(line);
The code doesn't give any error but it doesn't draw the line either.
In the same program, I also have a sphere:
var initScene = function () {
window.scene = new THREE.Scene();
window.renderer = new THREE.WebGLRenderer({
alpha: true
});
window.renderer.setClearColor(0x000000, 0);
window.renderer.setSize(window.innerWidth, window.innerHeight);
window.renderer.domElement.style.position = 'fixed';
window.renderer.domElement.style.top = 0;
window.renderer.domElement.style.left = 0;
window.renderer.domElement.style.width = '100%';
window.renderer.domElement.style.height = '100%';
document.body.appendChild(window.renderer.domElement);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
directionalLight.position.set( 0, 0.5, 1 );
window.scene.add(directionalLight);
window.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
window.camera.position.fromArray([0, 150, 700]);
window.camera.lookAt(new THREE.Vector3(0, 160, 0));
window.addEventListener('resize', function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
}, false);
scene.add(camera);
// set up the sphere vars
var radius = 50,
segments = 16,
rings = 16;
// create a new mesh with
// sphere geometry - we will cover
// the sphereMaterial next!
var sphereMaterial =
new THREE.MeshLambertMaterial(
{
color: 0xCC0000
});
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(
radius,
segments,
rings),
sphereMaterial);
// add the sphere to the scene
scene.add(sphere);
start = new THREE.Vector3(20, 10, 0);
end = new THREE.Vector3(200, 100, 0);
var line = new THREE.Line3(start, end);
scene.add(line);
renderer.render(scene, camera);
};
initScene();
I only see the sphere on the screen. Can you please tell me where I am wrong?
ADLADS (A Day Late and A Dollar Short):
From http://threejs.org/docs/
Line3 is one of many math objects of three.js that can be used to compute geometric stuff. Others are:
Box2 Box3 Color Euler Frustum Line3 Math Matrix3 Matrix4 Plane Quaternion Ray Sphere Spline Triangle Vector2 Vector3 Vector4
Say you had your "line", a Line3 object and "plane", a Plane object. You could check if the line intersected the plane by doing plane.intersectsLine(line). Would give true or false.
NONE OF THESE MATH OBJECTS (including Line3's) are Object3D's, the things to be rendered.
Here's the scoop:
1) Make the scene, the camera, and the renderer.
2) Add Object3D's to the scene.
2a) Object3D's can be Points, Lines, or Meshes.
2b) Points, Lines, and Meshes are made of Geometries and Materials.
2c1) for Points and Lines, the Geometries contain vertices(Vector3's) and faces(Face3's). Do "vertices.push" or "faces.push".
2c2) for Meshes, Geometries can be: Box Circle Cylinder Dodecahedron Extrude Icosahedron Lathe Octahedron Parametric Plane Polyhedron Ring Shape Sphere Tetrahedron Text Torus TorusKnot Tube
3) Do "renderer.render(scene, camera)".
Thanks for the question. It straightened me out.
For the sphere, you create a geometry (SphereGeometry) and pass it as argument to create a mesh (sphere) that has a material, so it can be drawed. Your line is a 2-vertices geometry, you need to create the corresponding mesh :
var lineMesh=new THREE.Line(
line,//the line3 geometry you have yet
new THREE.LineBasicMaterial({color:0x0000ff})//basic blue color as material
);
scene.add(lineMesh);

Draw a circle (not shaded) with Three.js

I am trying to draw a circle very similar to the orbital patterns on this website. I would like to use Three.js instead of pure WebGL.
Three.js r50 added CircleGeometry. It can be seen (albeit with a face) in the WebGL Geometries example.
The first vertex in the geometry is created at the center of the circle (in r84, see CircleGeometry.js line 71, in r65, see CircleGeometry.js line 18), which is nifty if you are going for that "full Pac-Man" or "uninformative pie chart" look. Oh, and it appears to be necessary if you are going to use any material aside from LineBasicMaterial / LineDashedMaterial.
I've verified that the following code works in both r60 & r65:
var radius = 100,
segments = 64,
material = new THREE.LineBasicMaterial( { color: 0x0000ff } ),
geometry = new THREE.CircleGeometry( radius, segments );
// Remove center vertex
geometry.vertices.shift();
// Non closed circle with one open segment:
scene.add( new THREE.Line( geometry, material ) );
// To get a closed circle use LineLoop instead (see also #jackrugile his comment):
scene.add( new THREE.LineLoop( geometry, material ) );
PS: The "docs" now include a nice CircleGeometry interactive example: https://threejs.org/docs/#api/geometries/CircleGeometry
The API changed slightly in newer versions of threejs.
var segmentCount = 32,
radius = 100,
geometry = new THREE.Geometry(),
material = new THREE.LineBasicMaterial({ color: 0xFFFFFF });
for (var i = 0; i <= segmentCount; i++) {
var theta = (i / segmentCount) * Math.PI * 2;
geometry.vertices.push(
new THREE.Vector3(
Math.cos(theta) * radius,
Math.sin(theta) * radius,
0));
}
scene.add(new THREE.Line(geometry, material));
Modify segmentCount to make the circle smoother or more jagged as needed by your scene. 32 segments will be quite smooth for small circles. For orbits such as those on the site you link you, you may want to have a few hundred.
Modify the order of the three components within the Vector3 constructor to choose the orientation of the circle. As given here, the circle will be aligned to the x/y plane.
I used code that Mr.doob references in this github post.
var resolution = 100;
var amplitude = 100;
var size = 360 / resolution;
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial( { color: 0xFFFFFF, opacity: 1.0} );
for(var i = 0; i <= resolution; i++) {
var segment = ( i * size ) * Math.PI / 180;
geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( Math.cos( segment ) * amplitude, 0, Math.sin( segment ) * amplitude ) ) );
}
var line = new THREE.Line( geometry, material );
scene.add(line);
This example is in the Three.js documentation:
var material = new THREE.MeshBasicMaterial({
color: 0x0000ff
});
var radius = 5;
var segments = 32; //<-- Increase or decrease for more resolution I guess
var circleGeometry = new THREE.CircleGeometry( radius, segments );
var circle = new THREE.Mesh( circleGeometry, material );
scene.add( circle );
I had to do this lol:
function createCircle() {
let circleGeometry = new THREE.CircleGeometry(1.0, 30.0);
circleGeometry.vertices.splice(0, 1); //<= This.
return new THREE.LineLoop(circleGeometry,
new THREE.LineBasicMaterial({ color: 'blue' }));
}
let circle = createCircle();
Reason: Otherwise, it doesn't draw a "pure" circle, there's a line coming from the center to the rim of the circle, even if you use LineLoop instead of Line. Splicing (removing) the first vertex from the array is a hack but seems to do the trick. :)
(Note that apparently, according to mrienstra's answer, "Oh, and it appears to be necessary if you are going to use any material aside from LineBasicMaterial / LineDashedMaterial.")
If you want thickness, though, you're screwed ("Due to limitations of the OpenGL Core Profile with the WebGL renderer on most platforms linewidth will always be 1 regardless of the set value.")... Unless you use: https://github.com/spite/THREE.MeshLine
Code example for that is here: https://stackoverflow.com/a/61312721/1599699
Well, I dunno when they added it - but TorusGeometry should do the job...
THREE TorusGeometry
const geometry = new THREE.TorusGeometry( 10, 3, 16, 100 );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const torus = new THREE.Mesh( geometry, material );
scene.add( torus );
Dunno, but I think it shouldn't be (much) more expensive than the line thingy and it's a buffer geometry and you may adjust size and material etc...
See the three.js sample http://mrdoob.github.com/three.js/examples/webgl_lines_colors.html to see how to draw colored lines.
A circle like the ones you cite is drawn as a large # of little straight segments. (Actually, the ones you show may be ellipses)
var getStuffDashCircle2 = function () {
var segment = 100, radius = 100;
var lineGeometry = new THREE.Geometry();
var vertArray = lineGeometry.vertices;
var angle = 2 * Math.PI / segment;
for (var i = 0; i < segment; i++) {
var x = radius * Math.cos(angle * i);
var y = radius * Math.sin(angle * i);
vertArray.push(new THREE.Vector3(x, y, 0));
}
lineGeometry.computeLineDistances();
var lineMaterial = new THREE.LineDashedMaterial({ color: 0x00cc00, dashSize: 4, gapSize: 2 });
var circle = new THREE.Line(lineGeometry, lineMaterial);
circle.rotation.x = Math.PI / 2;
circle.position.y = cylinderParam.trackHeight+20;
return circle;
}
I had some issues getting the other answers to work here -- in particular, CircleGeometry had an extra point at the center of the circle, and I didn't like the hack of trying to remove that vertex.
EllipseCurve does what I wanted (verified in r135):
const curve = new THREE.EllipseCurve(
0.0, 0.0, // Center x, y
10.0, 10.0, // x radius, y radius
0.0, 2.0 * Math.PI, // Start angle, stop angle
);
const pts = curve.getSpacedPoints(256);
const geo = new THREE.BufferGeometry().setFromPoints(pts);
const mat = new THREE.LineBasicMaterial({ color: 0xFF00FF });
const circle = new THREE.LineLoop(geo, mat);
scene.add(circle);

Categories

Resources