How can I get the dimensions of a three.js group? - javascript

I can get the dimensions of a mesh (Three.Mesh):
mymesh.geometry.computeBoundingBox()
var bbox = mymesh.geometry.boundingBox;
var bboxWidth = bbox.max.x - bbox.min.x;
var bboxHeight = bbox.max.y - bbox.min.y;
var bboxDepth = bbox.max.z - bbox.min.z;
But a group that has multiple meshes within it:
var mygroup = new THREE.Group();
doesn't have a computeBoundingBox()/boundingBox?

Thanks to one of the commentors, it was an easy solution:
var box = new THREE.Box3().setFromObject(theGroup);
var sizeX = box.getSize().x;
var sizeY = box.getSize().y;
var sizeZ = box.getSize().z;

Related

Why does Paper.js flip the coordinates of my point seemingly randomly?

I'm running into an issue with my code to make a fillet shape because the code will seemingly randomly flip the coordinates of the intersection point for reasons I can't find. Even when it is using the same equations, and the same vector is found to be the shortest, just changing the waypoint location very slightly changes the intersection point massively. I've run through the code a bunch of times, and can't tell why this would happen. I can't post images without 10 reputation, but if you run my code and change only the x coordinate for waypoint1 from 250 to 150 it has been breaking. Any help would be greatly appreciated!
var straightpath1 = new Path();
var straightpath2 = new Path();
//User inputs waypoints
var waypoint1 = new Point(250,450);
var waypoint2 = new Point(300,300);
var waypoint3 = new Point(500,600);
//Creates vectors to better visualize waypoints
straightpath1.add(waypoint1);
straightpath1.add(waypoint2);
straightpath1.strokeColor = 'red';
straightpath2.add(waypoint2);
straightpath2.add(waypoint3);
straightpath2.strokeColor = 'red';
//Find waypoint locations relative to waypoint2
var veca = new Point(waypoint1.x-waypoint2.x,waypoint2.y-waypoint1.y);
var vecb = new Point(waypoint3.x-waypoint2.x,waypoint2.y-waypoint3.y);
//Uses a circle to find intersections on each path to have
//equal length vectors being added to find angle bisector
var minpathlength = Math.min(straightpath1.length,straightpath2.length);
var bisectcirc = new Path.Circle(waypoint2, minpathlength-0.1);
var intersections1 = straightpath1.getIntersections(bisectcirc);
var intersections2 = straightpath2.getIntersections(bisectcirc);
//Creates angle bisector that fillet circle will be placed on
var intervec1 = new Point(intersections1[0].point.x-waypoint2.x,waypoint2.y-intersections1[0].point.y);
var intervec2 = new Point(intersections2[0].point.x-waypoint2.x,waypoint2.y-intersections2[0].point.y);
var addvec = intervec1 + intervec2;
var addpoint = new Point(addvec.x, addvec.y);
//Calculates slope and b intercept for this added vector
var addslope = (addpoint.y/addpoint.x);
var addbintercept = addpoint.y - (addslope*addpoint.x);
if(minpathlength == straightpath1.length){
//Finds equation for tangent line from shortest path that
//will intersect with the angle bisector
var slope = (veca.y/veca.x);
var bintercept = veca.y - (slope*veca.x);
var tangentslope = -(veca.x/veca.y);
var tangentbintercept = veca.y - (tangentslope*veca.x);
} else {
//This code runs if waypoint2 to waypoint3 is a shorter distance
var slope = (vecb.y/vecb.x);
var bintercept = vecb.y - (slope*vecb.x);
var tangentslope = -(vecb.x/vecb.y);
var tangentbintercept = vecb.y - (tangentslope*vecb.x);
}
//Finds point of intersection between the angle bisector line
//and the tangent line
if(addslope > 0){
var intersectslope = tangentslope - addslope;
} else {
var intersectslope = tangentslope + addslope;
}
if(tangentbintercept > 0){
var intersectbintercept = addbintercept - tangentbintercept;
} else {
var intersectbintercept = addbintercept + tangentbintercept;
}
//Finds x and y coordinate of the point of intersection
var intersectx = intersectbintercept/intersectslope;
var intersecty = (addslope*intersectx) + addbintercept;
//Draws circle to visualize intersection point relative to waypoint2
var intersect = new Point(intersectx+waypoint2.x, waypoint2.y-intersecty);
var intersectcirc = new Path.Circle(intersect, 5);
intersectcirc.fillColor = 'black';
//Finds dot product and cross product of original vectors to
//find a value for the angle of the vectors
var dotprod = veca.x*vecb.x+veca.y*vecb.y;
var crossprod = veca.x*vecb.y-veca.y*vecb.x;
var angle = Math.atan2(crossprod, dotprod);
//Path from waypoint2 to intersection to better visualize
var midpath = new Path();
midpath.add(waypoint2);
midpath.add(intersect);
midpath.strokeColor = 'blue';
//Bendradius is a user input to determine where the fillet
//will be located along the two vectors
var bendradius = midpath.length;
//Sets center point for circle
var filletposition = midpath.getPointAt(bendradius)
//Finds dynamic radius for circle that creates the fillet
//based on the bendradius and calculated angle
var h = (bendradius*Math.sin(angle/2));
var absh = Math.abs(h);
absh = absh + 0.2;
//Draws circle used for fillet
var fillet = new Path.Circle(filletposition,absh);
fillet.strokeColor = 'blue'
//Finds intersections between the drawn circle and the original paths
var intersections4 = straightpath1.getIntersections(fillet);
var intersections5 = straightpath2.getIntersections(fillet);
var intersections6 = midpath.getIntersections(fillet);
//Draws final fillet in three parts: waypoint1 to first intersection,
//arc of circle, intersection to waypoint3
var final1 = new Path();
final1.add(waypoint1);
final1.add(intersections4[0].point);
final1.strokeColor = 'black';
var final2 = new Path.Arc(intersections4[0].point, intersections6[0].point, intersections5[0].point);
final2.strokeColor = 'black';
var final3 = new Path();
final3.add(waypoint3);
final3.add(intersections5[0].point);
final3.strokeColor = 'black';

Position Labels on a coordinate System Easeljs

Hey I am trying to build the following picture in canvas using the library:EaselJS.
My Picture components are:
two circles - yellow and red and a light green background
a coordinate system from 0 to 1 with all the necessary labels which appear in the picture.
I have succeeded in my two goals.
I have build a Coordinate System based on stackoverflow discussion:
How to draw a full coordinate system with Easeljs?.
I have left with 2 main problems which concern me a lot:
I need to draw a rectangle(or square) which fits the coordinate system, the current rectangle is just a background.
Also I need to add 3 labels: 'Critical Index' on the x axis, 'Long-term Severity Index' on the y axis and a headline of Long-term.
I would happy if someone could help me with this issues
I am adding the source code:
$(function(){
var stage = new createjs.Stage('canvas2d');
var circle1 = new createjs.Shape();
var circle2 = new createjs.Shape();
var rect = new createjs.Rectangle(0, 0, 100, 100);
circle2.graphics.beginFill("yellow").drawCircle(0, 0, 300);
circle2.x = 500;
circle2.y = 0;
stage.addChild(circle2);
circle1.graphics.beginFill("red").drawCircle(0, 0, 150);
circle1.x = 500;
circle1.y = 0;
stage.addChild(circle1);
//stage.addChild(rect);
stage.update();
var coord_xaxis = new createjs.Shape();
stage.addChild(coord_xaxis);
var coord_yaxis = new createjs.Shape();
stage.addChild(coord_yaxis);
var coord_arrow_x = new createjs.Shape();
//stage.addChild(coord_arrow_x);
var coord_arrow_y = new createjs.Shape();
//stage.addChild(coord_arrow_y);
var coord_xaxis_lines = new createjs.Shape();
stage.addChild(coord_xaxis_lines);
var coord_yaxis_lines = new createjs.Shape();
stage.addChild(coord_yaxis_lines);
/**$('#canvas2d').width()/15**/
var axis_center_x = $('#canvas2d').width()/15;
var axis_center_y = $('#canvas2d').height()/1.10;
var xaxis_width = $('#canvas2d').width()-0.05*$('#canvas2d').width();
var yaxis_width = $('#canvas2d').height()-0.05*$('#canvas2d').height();
var axis_start_x = ($('#canvas2d').width()-xaxis_width)/2;
var axis_start_y = ($('#canvas2d').height()-yaxis_width)/6;
var axis_strokewidth = 2;
coord_xaxis.graphics.setStrokeStyle(axis_strokewidth,'round').beginStroke('#000');
coord_xaxis.graphics.moveTo(axis_start_x, axis_center_y).lineTo(axis_start_x+xaxis_width, axis_center_y);
coord_yaxis.graphics.setStrokeStyle(axis_strokewidth,'round').beginStroke('#000');
coord_yaxis.graphics.moveTo(axis_center_x, axis_start_y).lineTo(axis_center_x, axis_start_y+yaxis_width);
// draw coordsys arrow for x-axis
var arrwidth = 5;
var arrxtnd = 5;
coord_arrow_x.graphics.beginFill('#000');
coord_arrow_x.graphics.setStrokeStyle(axis_strokewidth,'round').beginStroke('#000');
coord_arrow_x.graphics.moveTo(axis_center_x, axis_start_y-arrwidth/2).lineTo(axis_center_x+arrwidth, axis_start_y+arrwidth+arrxtnd).lineTo(axis_center_x-arrwidth, axis_start_y+arrwidth+arrxtnd).lineTo(axis_center_x, axis_start_y-arrwidth/2);
coord_arrow_x.graphics.endFill();
// draw coordsys arrow for y-axis
coord_arrow_y.graphics.beginFill('#000');
coord_arrow_y.graphics.beginStroke('#000');
coord_arrow_y.graphics.moveTo(axis_start_x+xaxis_width+arrwidth/2, axis_center_y).lineTo(axis_start_x+xaxis_width-arrwidth-arrxtnd, axis_center_y+arrwidth).lineTo(axis_start_x+xaxis_width-arrwidth-arrxtnd, axis_center_y-arrwidth).lineTo(axis_start_x+xaxis_width+arrwidth/2, axis_center_y);
coord_arrow_y.graphics.endFill();
var stepdist = xaxis_width/5.25;
var steplinew = 6;
// 10 horizontal lines
var xlines = 10;
var labels_x = [];
for(var i=xlines;i>=0;i--) {
// little black marker
coord_yaxis_lines.graphics.setStrokeStyle(1,'round').beginStroke('#000');
coord_yaxis_lines.graphics.moveTo(axis_center_x-steplinew, axis_center_y+(-i/2)*stepdist).lineTo(axis_center_x+steplinew, axis_center_y+(-i/2)*stepdist);
// labels
labels_x[i] = new createjs.Text('x', '14px Arial', '#333');
labels_x[i].x = axis_center_x-12;
labels_x[i].y = axis_center_y+(-i/2)*stepdist-6; // move up a bit
stage.addChild(labels_x[i]);
labels_x[i].text = (i/10);
labels_x[i].textAlign = 'right';
}
// 12 orthogonal lines
var stepdist2 = xaxis_width/6.5;
var steplinew2 = 6;
var ylines = 10;
var labels_y = [];
for(var i=ylines;i>=1;i--) {
// dont overdraw y-axis-line
// little black marker
coord_xaxis_lines.graphics.setStrokeStyle(1,'round').beginStroke('#000');
coord_xaxis_lines.graphics.moveTo(axis_center_x+(i/1.6)*stepdist2, axis_center_y-steplinew2).lineTo(axis_center_x+(i/1.6)*stepdist2, axis_center_y+steplinew2);
// labels
labels_y[i] = new createjs.Text('x', '14px Arial', '#333');
labels_y[i].x = axis_center_x+(i/1.6)*stepdist2; // move up a bit
labels_y[i].y = axis_center_y+12;
stage.addChild(labels_y[i]);
labels_y[i].text = (i/10);
labels_y[i].textAlign = 'center';
}
stage.update();
})
#canvas2d{
background-color: #32CD32;
}
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas2d" width="500" height="500"></canvas>
The syntax for creating a rectangle in EaselJS is just the same as making a circle. The difference lies when calling drawRect instead of drawCircle in the graphics chain.
I've added a rectangle with arbitrary position and size values to match your overall code style, and because I couldn't find any criteria quickly. I also removed the background color on the CSS.
As for the addition of labels on each axis, I highly recommend you to use DOM instead. EaselJS support for text is almost unusable. Even EaselJS itself recommends you to use a DOMElement instead of the Text DisplayObj. More on DOMElement here.
Personally, I think it would be a lot easier to get to your desired result by using pure DOM instead of canvas work, unless you're doing some heavy user-interaction-based animation stuff.
$(function(){
var stage = new createjs.Stage('canvas2d');
var circle1 = new createjs.Shape();
var circle2 = new createjs.Shape();
var rect = new createjs.Shape();
rect.graphics.f("green").drawRect(33, 0, 500, 455);
stage.addChild(rect);
circle2.graphics.beginFill("yellow").drawCircle(0, 0, 300);
circle2.x = 500;
circle2.y = 0;
stage.addChild(circle2);
circle1.graphics.beginFill("red").drawCircle(0, 0, 150);
circle1.x = 500;
circle1.y = 0;
stage.addChild(circle1);
stage.update();
var coord_xaxis = new createjs.Shape();
stage.addChild(coord_xaxis);
var coord_yaxis = new createjs.Shape();
stage.addChild(coord_yaxis);
var coord_arrow_x = new createjs.Shape();
//stage.addChild(coord_arrow_x);
var coord_arrow_y = new createjs.Shape();
//stage.addChild(coord_arrow_y);
var coord_xaxis_lines = new createjs.Shape();
stage.addChild(coord_xaxis_lines);
var coord_yaxis_lines = new createjs.Shape();
stage.addChild(coord_yaxis_lines);
/**$('#canvas2d').width()/15**/
var axis_center_x = $('#canvas2d').width()/15;
var axis_center_y = $('#canvas2d').height()/1.10;
var xaxis_width = $('#canvas2d').width()-0.05*$('#canvas2d').width();
var yaxis_width = $('#canvas2d').height()-0.05*$('#canvas2d').height();
var axis_start_x = ($('#canvas2d').width()-xaxis_width)/2;
var axis_start_y = ($('#canvas2d').height()-yaxis_width)/6;
var axis_strokewidth = 2;
coord_xaxis.graphics.setStrokeStyle(axis_strokewidth,'round').beginStroke('#000');
coord_xaxis.graphics.moveTo(axis_start_x, axis_center_y).lineTo(axis_start_x+xaxis_width, axis_center_y);
coord_yaxis.graphics.setStrokeStyle(axis_strokewidth,'round').beginStroke('#000');
coord_yaxis.graphics.moveTo(axis_center_x, axis_start_y).lineTo(axis_center_x, axis_start_y+yaxis_width);
// draw coordsys arrow for x-axis
var arrwidth = 5;
var arrxtnd = 5;
coord_arrow_x.graphics.beginFill('#000');
coord_arrow_x.graphics.setStrokeStyle(axis_strokewidth,'round').beginStroke('#000');
coord_arrow_x.graphics.moveTo(axis_center_x, axis_start_y-arrwidth/2).lineTo(axis_center_x+arrwidth, axis_start_y+arrwidth+arrxtnd).lineTo(axis_center_x-arrwidth, axis_start_y+arrwidth+arrxtnd).lineTo(axis_center_x, axis_start_y-arrwidth/2);
coord_arrow_x.graphics.endFill();
// draw coordsys arrow for y-axis
coord_arrow_y.graphics.beginFill('#000');
coord_arrow_y.graphics.beginStroke('#000');
coord_arrow_y.graphics.moveTo(axis_start_x+xaxis_width+arrwidth/2, axis_center_y).lineTo(axis_start_x+xaxis_width-arrwidth-arrxtnd, axis_center_y+arrwidth).lineTo(axis_start_x+xaxis_width-arrwidth-arrxtnd, axis_center_y-arrwidth).lineTo(axis_start_x+xaxis_width+arrwidth/2, axis_center_y);
coord_arrow_y.graphics.endFill();
var stepdist = xaxis_width/5.25;
var steplinew = 6;
// 10 horizontal lines
var xlines = 10;
var labels_x = [];
for(var i=xlines;i>=0;i--) {
// little black marker
coord_yaxis_lines.graphics.setStrokeStyle(1,'round').beginStroke('#000');
coord_yaxis_lines.graphics.moveTo(axis_center_x-steplinew, axis_center_y+(-i/2)*stepdist).lineTo(axis_center_x+steplinew, axis_center_y+(-i/2)*stepdist);
// labels
labels_x[i] = new createjs.Text('x', '14px Arial', '#333');
labels_x[i].x = axis_center_x-12;
labels_x[i].y = axis_center_y+(-i/2)*stepdist-6; // move up a bit
stage.addChild(labels_x[i]);
labels_x[i].text = (i/10);
labels_x[i].textAlign = 'right';
}
// 12 orthogonal lines
var stepdist2 = xaxis_width/6.5;
var steplinew2 = 6;
var ylines = 10;
var labels_y = [];
for(var i=ylines;i>=1;i--) {
// dont overdraw y-axis-line
// little black marker
coord_xaxis_lines.graphics.setStrokeStyle(1,'round').beginStroke('#000');
coord_xaxis_lines.graphics.moveTo(axis_center_x+(i/1.6)*stepdist2, axis_center_y-steplinew2).lineTo(axis_center_x+(i/1.6)*stepdist2, axis_center_y+steplinew2);
// labels
labels_y[i] = new createjs.Text('x', '14px Arial', '#333');
labels_y[i].x = axis_center_x+(i/1.6)*stepdist2; // move up a bit
labels_y[i].y = axis_center_y+12;
stage.addChild(labels_y[i]);
labels_y[i].text = (i/10);
labels_y[i].textAlign = 'center';
}
stage.update();
})
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas2d" width="500" height="500"></canvas>

Why mesh created with ThreeBSP.js is not working properly with any material other than MeshNormalMaterial?

The dice looks like a dice only if I use MeshNormalMaterial in the second last line (result = resultBSP.toMesh(materialNormal);). With any other material it just looks like a cube with no subtraction (dots) on it. The ThreeBSP (ThreeCSG upgrade) library I am using is located here.
There is no problem with using the MeshNormalMaterial. It just doesn't have almost any options to modify it. (It doesn't take parameters like other materials).
Here is my function that I am using to create a dice:
function buildDice(){
var materialNormal = new THREE.MeshNormalMaterial();
var diceCube = new THREE.Mesh( new THREE.BoxGeometry(100,100,100), materialNormal);
diceCube.position.x = 0;
diceCube.position.y = 50;
diceCube.position.z = 0;
diceCube.geometry.computeFaceNormals();
diceCube.geometry.computeVertexNormals();
var cubeBSP = new ThreeBSP(diceCube);
var sphereGeometry = new THREE.SphereGeometry(75,16,8);
var sphereMesh = new THREE.Mesh(sphereGeometry, materialNormal);
sphereMesh.scale.x = 0.17;
sphereMesh.scale.y = 0.17;
sphereMesh.scale.z = 0.17;
//coords of the spheres
var xPositions = [....]; // coordinates for xPositions of sphereMesh
var yPositions = [....];
var zPositions = [....];
var diceDots = new THREE.Geometry();
for(var i = 0; i < xPositions.length; i++){
sphereMesh.position.x = xPositions[i];
sphereMesh.position.y = yPositions[i];
sphereMesh.position.z = zPositions[i];
THREE.GeometryUtils.merge(diceDots, sphereMesh);
}
var dotsMesh = new THREE.Mesh(diceDots, materialNormal);
dotsMesh.geometry.computeFaceNormals();
dotsMesh.geometry.computeVertexNormals();
var dotsBSP = new ThreeBSP(dotsMesh);
var resultBSP = cubeBSP.subtract(dotsBSP);
result = resultBSP.toMesh(materialNormal);
scene.add(result);
}
It does work with other Materials, for example with a THREE.MeshPhongMaterial. This jsfiddle using your buildDice()-function may help you:
http://jsfiddle.net/L0rdzbej/152/
You have to update the mesh´s matrix before merging the geometry, and best not to use deprecated functions for this.
Three.js r73

How to create a dynamic ellipse using paper.path object in raphael.js

I am a newbie to rapheal js & I need to create a dynamic ellipse only using paper.path() object.
Although we can do it using paper.ellipse(), but I need it to be done by only in path manner on demand of pre-exist code. I googled for it and only get the solution for circle2path().
Let me give a example to describe.
var paper = Raphael(10,10, 250, 250);
var start_x = 170;//this has to be dynamic
var start_y = 160;// so these are also
var r_x = 40;
var r_y = 35;
var ellipse = paper.ellipse(start_x,start_y,r_x,r_y);
// here instead of paper.ellipse, I need to use paper.path()
//for example I used path to create circle
var radius = 50;
var circle_path = "M"+ (start_x)+ (start_y-radius)+"A"+ radius+radius+0+1+1+(start_x-0.1)+(start_y-radius)+ "z";
var circle = paper.path(circle_path);
Its working properly for circle. Is there any way to do with ellipse.
Thanks in advance.
Eureka.........
I got a solution from this question .
var paper = Raphael(10,10, 250, 250);
var start_x = 170;//this has to be dynamic
var start_y = 160;// so these are also
var r_x = 40;
var r_y = 35;
var ellipse = [["M", (start_x - r_x), (start_y)], ["a", r_x, r_y ,0, 1,1, 0,0.1 ],"z"];
var draw = paper.path(ellipse);
This is it, what I want. So we can create a function for it.
var ellipse2path = function(start_x,start_y,r_x,r_y){
return [["M", (start_x - r_x), (start_y)], ["a", r_x, r_y ,0, 1,1, 0,0.1 ],"z"];
};

How to draw circular segment using paper.js

How to draw circular segment using paper.js
I want to draw the circular segments as shown in the image. Each segment is independent and will later be used for interactive purposes.
I tried something like
//Temporary background circle
var keys = new Path.Circle(view.center, 130);
keys.fillColor = '#F1F1F1';
var home = new Path.Circle(view.center, 50);
home.fillColor = '#ee2a33';
var start = new Point(view.center.x, view.center.y-130);
var through = new Point(view.center.x-125, view.center.y-40);
var to = new Point(view.center.x-130, view.center.y);
var path = new Path.Arc(start, through, to);
path.strokeColor = 'black';
path.fillColor = 'green';
And it renders something like below
After several attempts, I came up with this. If anyone needs the same thing for whatever reason, maybe this will help.
//Creating keys
var arcOne = createSegment('#f1f1f1');
var arcTwo = createSegment('#666666');
var arcThree = createSegment('#333333');
var arcFour = createSegment('#666666');
var arcFive = createSegment('#999999');
var arcSix = createSegment('#000000');
arcTwo.rotate(-60, view.center);
arcThree.rotate(-120, view.center);
arcFour.rotate(60, view.center);
arcFive.rotate(120, view.center);
arcSix.rotate(180, view.center);
//center white
var center = new Path.Circle(view.center, 50);
center.fillColor = '#F1F1F1';
//Create Each segment
function createSegment(fillcolor){
//Segment One
var start = new Point(view.center.x, view.center.y-130);
var through = new Point(view.center.x-90, view.center.y-94);
var to = new Point(view.center.x-113, view.center.y-64);
var name = Path.Arc(start, through, to);
name.add(new Point(view.center.x, view.center.y));
name.add(new Point(view.center.x, view.center.y-130));
name.fillColor = fillcolor;
return name;
}

Categories