Set and clone works differently - javascript

i have some doubts about Set and clone on Three js, im trying to render a scene where a sphere moves trought x axis and the camera follow the move with the lookAt, i tryed to do by myself the example on the book learning three js, but i didnt used the clone and my scene did the same but i couldnt see the sphere, with the clone i could see the sphere can someone explain me why that happen??
here is the 2 different codes:
sphere.position.copy(new THREE.Vector3(x,10,0));
sphere.position.set(new THREE.Vector3(x,10,0));
the first shows the sphere the second not :S

To elaborate on what Derte said already - set basically works like
function set(_x,_y,_z){
this.x = _x;
this.y = _y;
this.z = _z;
}
whereas copy works like:
function copy(v3){
this.x = v3.x;
this.y = v3.y;
this.z = v3.z;
}
you're passing innapropriate parameters to the set function, so it is throwing an error internally in all likelyhood. hit ctrl+shift+i in chrome to check the console, and you'll probably see that after it executes the first line fine with copy, it's throwing an error when you try to do set with (THREE.Vector3) as arguments instead of (float,float,float)

position is THREE.Vector3
look at reference
and implementation
Vector3.set takes 3 values : numbers x,y and z
Vector3.copy takes Vector3

Related

draw function not looping as expected

I'm a beginner on here, so apologies in advance for naivety. I've made a simple image on Brackets using Javascript, trying to generate circles with random x and y values, and random colours. There are no issues showing when I open the browser console in Developer Tools, and when I save and refresh, it works. But I was expecting the refresh to happen on a loop through the draw function. Any clues as to where I've gone wrong?
Thanks so much
var r_x
var r_y
var r_width
var r_height
var x
var y
var z
function setup()
{
r_x = random()*500;
r_y = random()*500;
r_width = random()*200;
r_height = r_width;
x = random(1,255);
y= random(1,255);
z= random(1,255);
createCanvas(512,512);
background(255);
}
function draw()
{
ellipse(r_x, r_y, r_width, r_height);
fill(x, y, z);
}
Brackets.io is just your text editor (or IDE if you want to be technical) - so we can remove that from the equation. The next thing that baffles me is that something has to explicitly call your draw() method as well as the setup() method -
I'm thinking that you're working in some sort of library created to simplify working with the Canvas API because in the setup() method you're calling createCanvas(xcord,ycord) and that doesn't exist on it's own. If you want to rabbit hole on that task check out this medium article, it walks you thru all the requirements for creating a canvas element and then drawing on that canvas
Your also confirming that you're drawing at least 1 circle on browser refresh so i think all you need to focus on is 1)initiating your code on load and 2)a loop, and we'll just accept there is magic running in the background that will handle everything else.
At the bottom of the file you're working in add this:
// when the page loads call drawCircles(),
// i changed the name to be more descriptive and i'm passing in the number of circles i want to draw,
// the Boolean pertains to event bubbling
window.addEventListener("load", drawCircles(73), false);
In your drawCircles() method you're going to need to add the loop:
// im using a basic for loop that requires 3 things:
// initialization, condition, evaluation
// also adding a parameter that will let you determine how many circles you want to draw
function drawCircles(numCircles) {
for (let i = 0; i < numCircles; i++) {
ellipse(r_x, r_y, r_width, r_height);
fill(x, y, z);
}
}
here's a link to a codepen that i was tinkering with a while back that does a lot of the same things you are
I hope that helps - good luck on your new learning venture, it's well worth the climb!
Thank you so much for your help! What you say makes sense - I basically deleted the equivalent amount of code from a little training exercise downloaded through coursera, thinking that I could then essentially use it as an empty sandpit to play in. But there's clearly far more going on under the hood!
Thanks again!

Is object facing another

I'd like to derive a value for how much one object is facing another. For example if it is directly facing the value would be 1 and facing directly away -1.
I have the object's global position and a quaternion for orientation. I'm using three.js
This is what I have so far, but its not giving me numbers I would expect.
Storing the object orientation as 3 part vector:
const lookVector = new THREE.Vector3(0,0,1);
const direction = lookVector.clone().applyMatrix4(torsoMesh.matrix);
this.lookVector = direction.sub(this.worldPosition);
Then using this to derive an angle to another point:
angleTo(pointOfInterest){
const vectorToPOI = pointOfInterest.sub(this.worldPosition);
const angle = this.lookVector.angleTo(vectorToPOI);
return angle;
}
one way to achieve this is using dot product. It is very simple, you just normalize both vectors and multiply each component respectively, then sum them up. I won't go into more detail here, because there is loads of resources explaining this on the internet. But here is an example of how to do it in three.js:
this.lookVector.normalize();
pointOfInterest.normalize();
var angleValue = this.lookVector.dot(pointOfInterest);
this will give exactly what you asked for (just remember that by calling normalize() on a vector, you are modifying it).
angleValue is actually just the cosine of the angle between the two vectors, so another way would just be to do:
.
.
return Math.cos(angle);
hope I understood you question correctly.
I know the mesh objects keep rotation values in radians. Maybe you can have a "parent mesh" so to speak and its its rotation values to determine this.

Javascript: Simple Particle Motion, Particle Elastically Bouncing Off Other Particle

I've created this rather simple javascript; balls or 'molecules' moving around the screen. I was hoping to add to the functionality that when one ball comes into contact with another, they swap velocities. We don't need to worry about any angles, just when they come into contact with each other, the velocities swap. (Instead of changing the velocities though, in the code linked I've just coded a colour change)
I've been trying to call the function 'someplace' to recognise when the molecules touch, but I've had no luck with that. I don't really understand why.
Link to code:
http://jsbin.com/arokuz/5/
There seems to be three main problems:
The molecules seem to be randomly changing, rather than when two molecules touch.
When one sets the array to have say, 3 molecules, only two appear, the first is actually there, but unresponsive to .fillstyle changes, so invisible against the canvas
With the function method I would only be able to recognise when molecules in series (1 and 2 or 4 and 5) in the array touch...how could I check all the molecules?
You are only comparing a molecule with 2 other ones, which in fact might be anywhere.
Collision detection is a topic quite hard to solve, but if you want to have your idea
working quickly you might go for a n^2 algorithm with 2 nested for loops.
the code is quite expected :
// collision
for(var t = 0; t < molecules.length-1; t++)
for(var tt = t+1; tt < molecules.length; tt++) {
var p1 = molecules[t];
var p2 = molecules[tt];
if (sq(p1.x-p2.x) +sq(p1.y-p2.y) < sq(p1.radius+p2.radius) )
{
p1.collided = 8; // will diplay for next 8 frames
p2.collided = 8; // .
}
}
the fiddle is here :
http://jsbin.com/arokuz/10
The reason only two appear when three are made isn't because the first one doesn't render it is rather the last one doesn't, this is because of how you draw them by comparing its distance with the next one in the list - as it is the last there is no next and thus throws a null error and continues (check the console).
The reason why they seem to "randomly" detect collisions or not is because they are not checking against all other molecules - only the next in the list, unfortunately the only simply way to do it would be to go through all other balls for every ball and checking.
To get the molecules to detect distance you could use the pythagorean theorem, I typically use it such as:
var distx = Math.abs(molecule1.x - molecule2.x);
var disty = Math.abs(molecule1.x - molecule2.y);
var mindist = molecule1.radius + molecule2.radius;
return Math.sqrt(distx*distx+disty*disty) < mindist;

Drawing a Line in a html5 canvas using EaselJS

I am very new to Easel and HTML5 itself. I am trying to draw a line using on a canvas using EaselJS. The X- Co ordinate is fixedd to 100 and the Y-Co ordinate is got from a array list. The code that i have written is given below. Could please someone let me know where i am going wrong?
function myFunction(attachPoint)
{
//Code for canvas creation is written here.[Not shown];
//created a stage.
stage = new createjs.Stage(canvas.domElement());
//3. create some shapes.MagnitudeLessThanTwo is the array where we get the YAxis Coordinates from
alert("The lenght before function is"+MagnitudeLessThanTwo.length);
myShape = new drawLineGraph(MagnitudeLessThanTwo);
//4. finally add that shape to the stage
stage.addChild(myShape);
//5. set up the ticker
if (!createjs.Ticker.hasEventListener("tick")) {
createjs.Ticker.addEventListener("tick", ourTickFunction);
};
};
function drawLineGraph(dataList)
{
this.index=0;//To keep the track of the index of the array from which we get the Y Axis.
var graphics = new createjs.Graphics();
graphics.setStrokeStyle(1);
graphics.beginStroke("white");
graphics.moveTo(50,(dataList[this.index].magnitude)*100);
graphics.lineTo(50,(dataList[(this.index)++].magnitude)*100);
createjs.Shape.call(this,graphics);
this.tick = function() {
graphics.moveTo(100,(dataList[this.index].magnitude)*100);
graphics.lineTo(100,(dataList[(this.index)++].magnitude)*100);
stage.addChild(graphics);
};
};
drawLineGraph.prototype = new createjs.Shape(); //set prototype
drawLineGraph.prototype.constructor = drawLineGraph; //fix constructor pointer
I am getting the following Error.
"Object [object Object] has no method 'isVisible'"- This is inside the EaselJS Library.
There are a few issues here. The error you are seeing is because you are adding the Graphics to the Stage, and not the Shape.
The other issue is how the Graphics are modified in the tick:
this.tick = function() {
graphics.moveTo(100,(dataList[this.index].magnitude)*100);
graphics.lineTo(100,(dataList[(this.index)++].magnitude)*100);
stage.addChild(graphics);
};
You only need to add your Shape to the stage one time, and it will redraw your graphics each time every time the Stage is updated. Your tick call is adding new Graphics instructions every frame, so it will stack all those calls up, and eventually be really slow.
Make sure you clear your Graphics before you draw new things to it, unless you are trying to create an additive effect (and if you are, perhaps look into caching/updateCache to make it performant). Check out the "curveTo" and "updateCache" examples in the GitHub repository for usage.
Once you have added the Shape to the stage instead of the Graphics, feel free to post some follow up questions, and I can try and assist further.
Cheers :)

How to handle collisions with tile id javascript

Ive written a small game in JavaScript with the html5 canvas and am at the point of collision detection and getting rather confused.
I build my levels in tiled and then import the saved JSON file into the game.
In my level draw function i have a check to see if there are any layer properties and if the layer properties are collisions. If it does, that layer is returned and the loop carries on. When finished, the layer that was returned with collisions gets put through another loop so that the the tile values can be put into an array.
So in this array i have i have a series of arrays depending on how many rows of tiles there are in the layer, and these rows hold the data for that row for each tile.
What i would like to do is when the player x/y is in one of the tiles which doesn't equal 0, then collide.
How would i do this if all i have is the value that is in that tile space?
Here is a link to the live version of the game so you can see for yourself how the tiles are stored, i have put in some console.logs so you might want to use firebug or equivalent to look at that. To log in use
Username - guest
password - guest
TO clarify my question is: How do i create collisions between my player x/y and a tile value??
Thanks very much
UPDATE
Ok so i think im nearly there, my problem at the moment is how do i read the objects x and y out of the array and then check the collision, at the moment the collision detection on works with the last tile in the array (the bottom right of the screen), here is the code i implemented to go through the array:
this.check_coll = function(array,posX, posY){
var collided = false,
block_x,
block_y,
block_cx,
block_cy,
combined_hw = 32,
combined_hh = 32,
player_cx = posX+(32/2),
player_cy = posY+(32/2);
array.forEach(function(value,i){
//get obj x
block_x = value[1];
//get obj y
block_y = value[2];
block_cx = block_x+(32/2);
block_cy = block_y+(32/2);
collided = Math.abs(player_cx - block_cx)< combined_hw
&& Math.abs(player_cy - block_cy)< combined_hh;
});
return collided;
}
Any ideas guys??

Categories