Need help for javascript and trigonometry - javascript

http://jsfiddle.net/techsin/CxFRC/15/ all chrome only click and drag, up and back arrow.
pastebin.com/gXS1J7zw
The Problem: I can't make c=$('.con') go/translate sideways. I have managed to do front and backward. But I cant workout the formula for sideways.
This is my first attempt. Use arrows keys, forward and backward works are in different function. But leftRight don't.
Code in question: you don't need to worry about rest of the code main logic for right left lies here. I have tried finding the perpendicular angle but it behaves opposite and then opposite of opposite.
First code that works and need no attention:
function forwBack(x){
az+= x*(Math.cos((Math.PI/180)*ry))*Math.cos((Math.PI/180)*rx)*speed;
ax-= x*(Math.sin((Math.PI/180)*ry))*Math.cos((Math.PI/180)*rx)*speed;
ay+= x*(Math.sin((Math.PI/180)*rx))*speed;
}
Now code that doesn't do what I want... translate perpendicular to vector.
function rightLeft(x){
az+= Math.sin(ry*(Math.PI/180))*(Math.cos((rx+90)*(Math.PI/180))*speed*x);
ax-= Math.cos(ry*(Math.PI/180))*(Math.cos((rx+90)*(Math.PI/180))*speed*x);
ay+= Math.sin((rx+90)*(Math.PI/180))*speed*x;
}
x is sign which determines left/right or forward/backward. Speed is hypotenuse here. Pi/180 for deg to radians. And 180/Pi for radians to deg. (rotation around x axis) rx and ry are defined in function ch..and represent rotation of main(.ma) container. rx is defined by vertical movement of mouse.
I don't need to do this, but I want to. I want to make 3d explorer like a hall.. Just for fun. I used to do this kind of stuff in flash like 9 years ago. I was a kid then.
MAIN problem is that sideways is not always -x or +x, it depends on how much outer container has been rotated(around xyz). So if m is rotated 90 around y axis only telling c to move x+ would make c actually look like it's going back or reducing in z.
After trying two days straight I can't fix this.
http://jsfiddle.net/techsin/hGkMj/1/ -- Checking out 3d
http://jsfiddle.net/techsin/hGkMj/6/ -- Checking out 3d
http://jsfiddle.net/techsin/9YjSC/3 I made this to get clear idea of what I was trying to do. Move mouse, & Use arrow keys. Need to click in the preview window.

I found the problem. In your function rightLeft, you are inverting x and y.
I rewrote the function and it is working fine:
function rightLeft(x){
var dAy = 0 ;
var dAz = Math.cos((ry+90)*(Math.PI/180))*speed*x;
var dAx = Math.sin((rx+90)*(Math.PI/180))*speed*x;
console.log("dAx = " + dAx + " dAz = " + dAz + " dAy = " + dAy);
ax-= dAx;
az+= dAz;
ay+= dAy;
}
Hope this helps!

Related

Rotation around a point causes weird glitches in THREE.js

Every element from my scene is made of a chain of 3 Object3Ds. The order parent-to-child is cellPivot -> modifier -> setup
setup's purpose is to permanently align a loaded object by resizing / giving some padding that must always be there. It is not supposed to be changed once set
modifier's purpose is to actually perform the real transformation on the object
cellPivot's purpose is to allow me to drag modifier into a cell grid
An example why all this is needed: let's say I have a vertical door in an orthographic perspective that I wanna fit in a 1x1 space, so I give some padding on the x-axis to align the door in the center, similar to the picture below where the orange block is the door
Since I want to move this in any cell in the map, I use cellPivot's position to decide where. I can't use right away modifier since sometimes I wanna rotate the model inside the cell, which requires to modify both position and rotation (since my models are not built around (0, 0, 0), but along +X and +Z)
I have succesfully managed to rotate these doors by rotating modifier around the center of the model (which acts as a pivot). Here's the functions that does the rotation:
three.Object3D.prototype.pivot = function(pivot, f) {
pivot = lib.VecToVector3(three, pivot); // just a conversion between libs
this.position.sub(pivot);
f(this);
this.position.add(pivot);
return this;
};
three.Object3D.prototype.pivotRotate = function(pivot, axis, theta, rotational = false, abs = false) {
if(abs)
theta -= this.rotation.y; /// not good, handles only y
this.pivot(pivot, () => this.position.applyAxisAngle(axis, theta));
if(rotational)
this.rotateOnAxis(axis, theta);
return this;
};
The line that rotates the door and works:
this.o3d.userData.modifier.pivotRotate(this.o3d.userData.center, new three.Vector3(0, 1, 0), this.rot, true);
I'm now trying to do something similar with the player too. I record what keys are pressed, I calculate the normal of the vector of desired direction (if I press W and D I'll get (1, 1), if I press just W I'll get (0, 1)), after which I use the following line to detect the angle at which the user wanna move:
Math.atan2(-normal[1], normal[0]);
I have already tested that the angle is correct. On top of that, the codebase before "rotating around a pivot" used the same code and it worked fine
Everytime there's actually a direction the user wanna go, I'll run the following line:
this.o3d.userData.modifier.pivotRotate(this.o3d.userData.center, new three.Vector3(0, 1, 0), Math.atan2(-normal[1], normal[0]), true, true);
If the user just keeps a key pressed, then abs will make sure that no visible rotation is made (since theta will be 0)
Here's the problem: everytime I press A, be it in combination with W or S or not, the character will rotate like insane. I put after the line from above the following code to see what's happening:
com.log(new three.Euler().setFromQuaternion(this.o3d.userData.setup.getWorldQuaternion(new three.Quaternion())));
I'm getting this:
As you can see, x and z are reaching -pi, and y bouces back and forth. This does not happen for any other combination that does not contain key A
Update after 2 days:
I have rewrote my function like this:
I got these in console while trying to move in the problematic positions:
As it can be seen in the first log, my target is at rotation 0 and is going for -2.35..., but rotAfterRot is showing weird results..: -pi and -.78...
This is the result of running this.rotateOnAxis(axis, theta). I have changed this exact line with this.rotation.y += theta. Now everything is working as it should be: no weird -pi and rotAfterRot.y is actually theta
My guess is that rotateOnAxis is also counting other features of the object, like position, but still can't figure how it spits that -pi

How to detect collision between two images in javascript?

I am implementing a simple game where my car (an image) has to dodge obstacles which are circles (images). Now I am having problem making a collision detection method for the car and the circle. I want the circle to disappear as soon as the car collides with it. Right now I am using an id named 'y' to show if the car collides with the bluecircle. If it does the id is used by the <p> tag in my HTML code section and it should display text saying "COLLISION" but even when they intersect....nothing happens... :/
function Intersect(ax ,ay , aw , ah , bx , by , bw , bh){
return ax < bx + bw && bx < ax + aw && ay < by + bh && by < ay + ah;
}
if (Intersect(this.x,this.y,this.w,this.h,bluecircleArray[0].x,bluecircleArray[0].y,bluecircleArray[0].width,bluecircleArray[0].height)){
document.getElementById("y").innerHTML = "COLLISION";
}
I kind of think what you wrote for Intersect is actually an "IsContainedIn" function. The natural expression of Intersect should be this, with added parentheses to help with order of operations:
"(Is the right-side X edge of A contained in B, OR is the left-side X edge of A contained in B), AND, (Is the bottom-side Y edge of A contained in B, OR is the top-side Y edge of A contained in B)"
And, to elaborate, "contained in", would mean:
"Is this number between B's X/Y value, and B's X/Y value plus its width"
It's quite possible that in the end, the if clause will get quite large.
The main problem with your current equation is that all the statements are connected with "&&". I'm not sure if it's possible for all clauses to be simultaneously true, unless possibly one of them fits inside the other in an exact way.
If you're still having trouble writing it out, there might be some tutorials on "Axis-Aligned Bounding Box Collision" that could help with it - they may also be able to give visual samples to help you get a spatial idea of it in your mind.

How does collisions caculates when developing game in Build an HTML5 Game book

I don't understand authors login when calculating collisions between two circles (bubbles). Here is the Calculating collisions section.
Author writes:
The bubble being fired follows a set of coordinates defined by the
equations:
px = ex + tdx py = ey + tdy
where px and py are points on the trajectory of the bubble’s center
point. The calculation of px and py happens in jQuery’s animate method
and is the standard equation for moving a point along a line. Next,
we’ll calculate t at the closest point on this line to the center of
the bubble that we’re checking against:
var t = dx * distToBubble.x + dy * distToBubble.y;
I don't understand what t is and why it calculates by the following formula:
var t = dx * distToBubble.x + dy * distToBubble.y;?
This has little or nothing to do with programming, it is absolutely Math. So I think this question shouldn't be here, but I will answer it just for helping you out.
I don't understand what is t
The line of movement of the bubble being fired is defined by a parametric equation, wich parameter is the variable t
why it calculates by the following formula
This is kind of complex, the book just shows the final result of the following calculation. There is a formula to calculate the distance between a point and a line. In this case the point is the center of the target bubble and the line is represented by the parametric equiation previously shown. After you solve that, you can derive that equation to find the minimum distance.
Although there is an easier way to solve this. Using dot product between the origin of the target bubble and the coordinates of the shooted bubble with the parametric function and equal it to 0 (perpendicular intersection) you cand find the value for t.
The important point here is that the book already solved the problem for you and it is showing the final result so you can use it.
Good luck with your game!

Raphael JS: Get Point when Animation stops

I'm programming a small psychological experiment with Javascript and Raphael.
It's my first time using Raphael, and I'm not as good with it, as I want to be ;)
Basically, there is a clock and a small point which is running around it. When the test subject presses the space bar, the point should stop and its absolute X and Y position should be saved.
The animation and the reaction to the space bar press works just fine, but I have my problems with getting the absolute position of the point. I'm using a relative transform to move the point within the clock.
clock.customAttributes.along = function (v) {
var point = p.getPointAtLength(v * len);
return {
transform: "t" + [point.x, point.y] + "r" + point.alpha
};
};
You can look up the experiment here: http://narda.bplaced.net/
If you press the space bar, a new point is drawn at the position which is given by matrix.x(x,y) and matrix.y(x,y).
Is there a way to translate a relative transform into an absolute position? Or can I move the point with an absolute transform instead of a relative?
Thank you for any new approach.
Raphael buries the animation parameters in the object. It takes some nosing around, and I cannot run your code, but I think you'll find the current animation settings here:
console.log(clock._.transform)
It'll be an array, but you should be able to spot the "t" and then two floats might be your x and y.
Just use getBBox()
here is as example:
var m = Raphael("canvas");
var c = m.circle(50,50,1).attr({fill: "#000", stroke: "none"});
c.transform("t150,50")
console.log(c.getBBox().x);
And if you need absolute position add jquery offset
console.log(c.getBBox().x + $("#canvas").offset().left);

First person simulation with three.js using keyboard arrows

For my source, visit http://jsfiddle.net/fYtwf/
Background
I have a simple 3d simulation using three.js where the camera is surrounded in 3 dimensions by cubes. These cubes are to help visualise where the camera is looking until the view controls are coded and tested. I want to create a simple 3D application, where the camera is controlled via up, down, left and right keys. Just like moving your head
Issues
In my current application, when facing forward, and starting to look up, we are successful. However when we turn left 90 degrees, and we press the up arrow... The wrong thing happens. the camera increments the x axis, but because we're facing another direction, modifying the x axis ALONE is WRONG...
Now I'm assuming this is because some trigonometry is required to calculate the correct values for the z axis. However, my trig isn't brilliant.
Current
To get a better understanding of what i mean, please visit my jsfiddle : http://jsfiddle.net/fYtwf/
UP key ONLY increments X
DOWN key ONLY decrements X
LEFT key ONLY increments Y
RIGHT key ONLY decrements Y
Q key ONLY increments Z
W key ONLY decrements Z
( Q and W were only coded to try and help me understand. )
From my current understanding, when I press the UP key, X must increment and the Z axis must be modified based on what the current Y axis is. However I don't know the algorithm :(
So X and Z must be modified in the KEYUP code ( I think, please correct me if I am wrong )
// setRotateX, getRotateX, setRotateY and getRotateY are extended
// camera functions I wrote so I could work with degrees. Solution
// IS NOT required to use them, they just helped me
switch( key )
{
case KEYUP:
if ( camera.getRotateX() < 90 ){ // restrict so they cannot look overhead
camera.setRotateX( camera.getRotateX() + VIEW_INCREMENT );
}
break;
case KEYDOWN:
if ( camera.getRotateX() > -90 ){ // restrict so they cannot look under feet
camera.setRotateX( camera.getRotateX() - VIEW_INCREMENT );
}
break;
case KEYLEFT:
camera.setRotateY( camera.getRotateY() + VIEW_INCREMENT );
break;
case KEYRIGHT:
camera.setRotateY( camera.getRotateY() - VIEW_INCREMENT );
break;
}
There are a number of solutions to this problem, but since you only want the camera to rotate up, down, left, and right, the answer in this case is easy.
You just need to set the camera Euler order to "YXZ" like so:
camera.rotation.order = "YXZ"; // three.js r.65
If you do that, everything becomes very intuitive.
Here is an updated fiddle: http://jsfiddle.net/fYtwf/3/ (this demo is using r.54, however)
Once you change camera.rotation.z from it's default value of zero, things will become very confusing. So don't do that. :-)
three.js r.65
While this does not directly fix your code, I thought I'd mention that Three.js provides two ready-made controllers to navigate in FPS mode. They both use mouse for looking and can move, but should be rather simple to adapt to keyboard look and remove movement if needed. They are:
FirstPersonControls
PointerLockControls
I'd recommend the latter as a starting point because it's rather simple and the former confusingly has the looking code twice, probably as an artifact from old features.

Categories