This THREE.BoxHelper is wildly inaccurate, and the position of the cube is not accurate when drawing a line to it!?
See the proof of concept JSFiddle: https://jsfiddle.net/can35bj0/15/
cubeBox = new THREE.BoxHelper(cube, 0xffff00)
scene.add(cubeBox);
cube.position.copy(positionVector);
cubeTrace.geometry.vertices[cubeTrace.geometry.vertices.length - 1].copy(cube.position);
Why is this, and is there a way to fix this? So far I've come up empty...
p.s. scales and position need to be small vs. large
I've more or less concluded that this is due to a 'long vector' problem of THREE.js.
When an object (such as the square cube in the JSFiddle) is on a long arm from Origin compared to it's size, in this case the positionVector is roughly 100,000 units and the cube size is 0.001 units, positions become erratic and fluctuating as can be seen by the weird behavior of the Boxhelper. (Note that the cube is set to move slightly every second and the camera moves with it)
Related
See this question: Threejs Transform Matrix ordering
I'm drawing the orbits of the planets and having problems with changing inertial reference frames (I chose to align the three.js world coordinates with the viewed planet's inertial reference frame). But I need to force three.js to apply operations in the order shown below so the orbit is properly displayed (presently the orbit stays at world (0,0,0) and spins crazily).
The normal (physics) way to do this is to do the following in order:
zero position and rotation of the ellipse.
ellipse.position.set(0,0,0);
ellipse.rotation.set(0,0,0);
Apply Direction Cosine Matrix (matrix which changes reference frame).
ellipse.applyMatrix(DCM);
Translate orbit to be centered on orbiting body, where r is the radius vector of the planet.
ellipse.translateX(r.x);
ellipse.translateY(r.y);
ellipse.translateZ(r.z);
Rotate the ellipse.
ellipse.rotateZ(RAAN); // RAAN : right angle of ascending node
ellipse.rotateX(inc); // inc : orbit inclination
ellipse.rotateZ(ArgP); // ArgP : Argument of Periapsis.
Adjust for difference between center and focal point.
ellipse.translateX(-c);
Profit.
So I'm not sure if there's some kind of command flow in three.js that I'm not familiar with, or if node.js is causing asynchronous problems.
Okay. I just posted this, but found the solution for anyone who has the same problem in the future. If you want to apply things in a different order of operations than three.js wants you to (as seen in this post: Threejs Transform Matrix ordering).
Then you must use the applyMatrix function between each operation that you wish to do in a specific order.
Using the above as an example:
ellipse.position.set(0,0,0);
ellipse.rotation.set(0,0,0);
ellipse.updateMatrix();
ellipse.applyMatrix(DCM);
ellipse.updateMatrix();
ellipse.translateX(r.x);
ellipse.translateY(r.y);
ellipse.translateZ(r.z);
ellipse.updateMatrix();
ellipse.rotateZ(RAAN); // RAAN : right angle of ascending node
ellipse.rotateX(inc); // inc : orbit inclination
ellipse.rotateZ(ArgP); // ArgP : Argument of Periapsis.
ellipse.updateMatrix();
ellipse.translateX(-c);
ellipse.updateMatrix();
I'm trying to implement the code from this tutorial, but in much greater proportions (radius = 100000 units).
I don't know if the size matters but on my earth render the clouds have a strange render.
As the tutorial does, I'm using two spheres and three textures (earth map, bump map, clouds).
Here the result (that's worse if the clouds are closer):
More the clouds are closer of the planet surface, more this glitch is visible. If the clouds are sufficiently far (but that's not realistic) the problem disappears completely.
What can I do?
Use logarithmic depth buffer instead of the linear one. This is a very simple change, just enable logarithmicDepthBuffer when you create your THREE.WebGLRenderer like so:
var renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true});
Here's an example you can have a look at:
http://threejs.org/examples/#webgl_camera_logarithmicdepthbuffer
Using polygonOffset as suggested by LJ_1102 is a possibility, but it shouldn't be necessary.
What you're experiencing is z-fighting due to insufficient depth buffer resolution.
You basically have three options to counteract this:
Write / use a multi-texture shader that renders all three textures on one sphere.
Increase the distance between the sphere faces. / Decrease the distance between your near and far clipping planes.
Use polygonOffset and the POLYGON_OFFSET_FILL renderstate to offset depth values written by your outer sphere. Read more about polygonOffset here.
If I would like to have a camera, with 60° fov, then how to calculate the CSS3D perspective value?
perspective: ?;
perspective-origin: center center;
I've found a description about, how to calculate the projection matrix from perspective value, but I still don't really understand it: http://www.w3.org/TR/css-transforms-1/#perspective-matrix-computation
So if I have a given Field of View, and I know the element's offsetWidth/offsetHeight, then how should I calculate the needed perspective value?
And where are the near plane and the far plane?
I asked a similar question a few years ago and got the response below. The article linked has since changed, so I'm quoting the text since it no longer exists in the article (but there may still be other useful info).
If I'm reading it correctly, you have a pyramid with the base at [perspective px] away from the viewer. So if you want a 60° fov, you have a 30° triangle from the center to the corners and you need to find the length of the adjacent edge:
Math.pow( w/2*w/2 + h/2*h/2, 0.5 ) / Math.tan( 30 * Math.PI / 180 )
I think ;) It yields a perspective of 968 for a 1000x500 view, which seems about right from having played randomly with -webkit-perspective a fair bit
The CSS 3D Transforms Module working draft gives the following explanation:
perspective(<number>)
specifies a perspective projection matrix. This matrix maps a viewing cube onto a pyramid whose base is infinitely far away from the
viewer and whose peak represents the viewer's position. The viewable
area is the region bounded by the four edges of the viewport (the
portion of the browser window used for rendering the webpage between
the viewer's position and a point at a distance of infinity from the
viewer). The depth, given as the parameter to the function, represents
the distance of the z=0 plane from the viewer. Lower values give a
more flattened pyramid and therefore a more pronounced perspective
effect. The value is given in pixels, so a value of 1000 gives a
moderate amount of foreshortening and a value of 200 gives an extreme
amount. The matrix is computed by starting with an identity matrix and
replacing the value at row 3, column 4 with the value -1/depth. The
value for depth must be greater than zero, otherwise the function is
invalid.
I have recently started playing with canvas after seeing how easy it can be. My first project was just to keep a circle in its boundaries as it moves around. I made a few more things involving the movement of circles and now...
I'm currently working on bouncing two circles off of each other when they hit. You can see the example of that here: http://jsfiddle.net/shawn31313/QQMgm/7/
However, I would like to use a little more real world physics. At the moment, when the circles hit each other they just reverse their path.
As shown here:
// Dont be confused, this is just the Distance Formula
// We compare the distance of the two circles centers to the sum of the radii of the two
// circles. This is because we want to check when they hit each other on the surface
// and not the center.
var distance = Math.sqrt(Math.pow(c1.x - c2.x, 2) + Math.pow(c1.y - c2.y, 2));
var r1 = c1.rad;
var r2 = c2.rad;
if (distance < r1 + r2) {
// Change the slope of both circle
// I would like to figure out a more effecience way of bouncing the circles back
// However, I have no idea how to determine the angle the ball was struck,
// and with that information bounce it off at that angle
c1.xi = -c1.xi; // path is reversed
c1.yi = -c1.yi;
c2.xi = -c1.xi;
c2.yi = -c1.yi;
}
However, I would like the circles to go in opposite direction determined by the point and angle of intersection.
I am only in the 9th grade and not sure how the formula for something like this would look. But I know that it is possible because this kind of physics is present in many games. An example would be an 8-ball game. When the balls hit each other, they move across the table according to how the balls hit each other.
I would appreciate any tips on how to do this or if I should wait until I have a stronger understanding of Physics and Math in general.
too bad we can't draw a very simple scheme.
As far as physics is concerned, you know that the total momentum is conserved, see
http://en.wikipedia.org/wiki/Momentum
There is a good illustration and formulas here http://en.wikipedia.org/wiki/Elastic_collision#Two-_and_three-dimensional
You can simplify formulas if the two object have the same weight.
so now, let's consider the reference frame in which c2 is fixed and center in (0,0).
c1 velocity in this reference would be :
c1.xfi=c1.xi-c2.xi
c1.yfi=c1.yi-c2.yi
Now you have a collision when the distance between the two is the sum of radius. Consider the tangent plane of the two circles.
You now have to decompose the velocity of c1 into a tangent component, which is conserved, and a perpendicular (following the line between c1 and c2), which is transfered to c2.
Then you need to go back to your original reference frame.
(sorry i didn't give you the exact formulas but they are on the links I provided)
If I were doing this myself, I would implement the motion using Newtons law of restitution. Essentially this is a coefficient that relates approach and separation speed of 2 particles before/after impact and it has a value that depends on the material properties of your particles.
Your analysis will essentially amount to identifying the point of impact, then breaking down the approach velocities into components that are parallel and perpendicular to the line of centres of the circle at the point of impact.
The momentum of the particles is conserved perpendicular to the line of centres (so the velocities in that direction remain unchanged by the collision) and the law of restitution applies to the velocities parallel to the line of centres. Thus if you fix the coefficient of restitution (it has to be between 0 and 1) to some value of your choice you can use this law to calculate the separation speeds along the line of centres of your particles after collision using the value of the approach speeds.
If your particles are all of the same mass and radius then the calculations become simpler. You can model elastic collisions by setting the coefficient to 1 (this indicates that separation speed of the particles is the same as the approach speed) which is probably the easiest place to start. By changing the value you will see different behaviour between particles after collisions.
Sorry not to be able to write this all down in formula for you, but this is not really the appropriate place for it. Living in the UK I have no idea what "9th grade" is so I can't assess if the above is too advanced for your current level of education. Here in the UK this type of problem would typically be covered at A-level mathematics education level.
Hopefully though it will give you an indication of the terms and topics that you can teach yourself/ research in order to achieve your goal.
I want to check a collision between two Sprites in HTML5 canvas. So for the sake of the discussion, let's assume that both sprites are IMG objects and a collision means that the alpha channel is not 0. Now both of these sprites can have a rotation around the object's center but no other transformation in case this makes this any easier.
Now the obvious solution I came up with would be this:
calculate the transformation matrix for both
figure out a rough estimation of the area where the code should test (like offset of both + calculated extra space for the rotation)
for all the pixels in the intersecting rectangle, transform the coordinate and test the image at the calculated position (rounded to nearest neighbor) for the alpha channel. Then abort on first hit.
The problem I see with that is that a) there are no matrix classes in JavaScript which means I have to do that in JavaScript which could be quite slow, I have to test for collisions every frame which makes this pretty expensive. Furthermore I have to replicate something I already have to do on drawing (or what canvas does for me, setting up the matrices).
I wonder if I'm missing anything here and if there is an easier solution for collision detection.
I'm not a javascript coder but I'd imagine the same optimisation tricks work just as well for Javascript as they do for C++.
Just rotate the corners of the sprite instead of every pixel. Effectively you would be doing something like software texture mapping. You could work out the x,y position of a given pixel using various gradient information. Look up software texture mapping for more info.
If you quadtree decomposed the sprite into "hit" and "non-hit" areas then you could effectively check to see if a given quad tree decomposition is all "non-hit", "all hit" or "possible hit" (ie contains hits and non-hit pixels. The first 2 are trivial to pass through. In the last case you then go down to the next decomposition level and repeat the test. This way you only check the pixels you need too and for large areas of "non-hit" and "hit" you don't have to do such a complex set of checks.
Anyway thats just a couple of thoughts.
I have to replicate something I already have to do on drawing
Well, you could make a new rendering context, plot one rotated white-background mask to it, set the compositing operation to lighter and plot the other rotated mask on top at the given offset.
Now if there's a non-white pixel left, there's a hit. You'd still have to getImageData and sift through the pixels to find that out. You might be able to reduce that workload a bit by scaling the resultant image downwards (relying on anti-aliasing to keep some pixels non-white), but I'm thinking it's probably still going to be quite slow.
I have to test for collisions every frame which makes this pretty expensive.
Yeah, I think realistically you're going to be using precalculated collision tables. If you've got space for it, you could store one hit/no hit bit for every combination of sprite a, sprite b, relative rotation, relative-x-normalised-to-rotation and relative-y-normalised-to-rotation. Depending on how many sprites you have and how many steps of rotation or movement, this could get rather large.
A compromise would be to store the pre-rotated masks of each sprite in a JavaScript array (of Number, giving you 32 bits/pixels of easily &&-able data, or as a character in a Sring, giving you 16 bits) and && each line of intersecting sprite masks together.
Or, give up on pixels and start looking at eg. paths.
Same problem, an alternative solution. First I use getImageData data to find a polygon that surrounds the sprite. Careful here because the implementation works with images with transparent background that have a single solid object. Like a ship. The next step is Ramer Douglas Peucker Algorithm to reduce the number of vertices in the polygon. I finally get a polygon of very few vertices easy and cheap to rotate and check collisions with the other polygons for each sprite.
http://jsfiddle.net/rnrlabs/9dxSg/
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var img = document.getElementById("img");
context.drawImage(img, 0,0);
var dat = context.getImageData(0,0,img.width, img.height);
// see jsfiddle
var startPixel = findStartPixel(dat, 0);
var path = followPath(startPixel, dat, 0);
// 4 is RDP epsilon
map1 = properRDP(path.map, 4, path.startpixel.x, path.startpixel.y);
// draw
context.beginPath();
context.moveTo(path.startpixel.x, path.startpixel.x);
for(var i = 0; i < map.length; i++) {
var p = map[i];
context.lineTo(p.x, p.y);
}
context.strokeStyle = 'red';
context.closePath();
context.stroke();