Raphael.js get rectangle coords after transform - javascript

I have a small little game I'm making in javascript and Raphael.js(which i'm fairly new to) and I'm making a turret essentially, just a circle that has a rectangle swivel around it. And that works fine and dandy!
Code for transform is :
this.self = this.self.animate({ transform : this.transform }, 250);
However, I need to find the coords of the rectangle after I animate it, but getBBox() keeps getting the same coords. Does anyone have any suggestions? A visual picture of the transform would be:
So I need the turret coords after the transformation. I need to find the front of the turret so I know where the bullet needs to come out of! Any advice will be appreciated!

By using the rotation number, will help you to find the coordinates. Lets say the rotation angel is q = 45 degrees.
This means that y changes by asin(q) and x changes by a - acos(q).
EDIT
Pay attention to all cases. In this particular case, both coordinates got decreased, but if you turn to southeast, then y increases and x decreases. Or if northwest: y and x decrease.

Transform is just a visual effect, it's not affects on coordinates.
You know width of turret and you know rotation angle.
Use sin & cos to calculate new coords.
X = Math.cos((i * Math.PI) / 180) * R + x;
Y = Math.sin((i * Math.PI) / 180) * R + y;
i - angle
R - width of turret
x and y - turret offset

Related

Find point coordinates on a plane

Could you help me please find coordinates of point on a plane?
I try to find coordinates of the point.
If working with JavaScript, you would employ Math.sin() and Math.cos()
If you imagine a unit circle (a circle with radius 1),
and a straight line A starting from the circle's center going towards the
edge,
and you know the line A's angle (in radians). Or the angle in degrees to a reference line which points straight right (on your drawing, the reference line would be +90 degrees to the one which shows radius), in which case if line A is in the top half of the circle the angle would be positive, while if in the bottom half of the circle (like your drawing) the angle would be negative.
Of course, if you only have the angle in degrees, you would have to convert it to radians before passing it to sine and cosine functions. It is a simple operation, you can find many examples online:
function degrees_to_radians(degrees)
{
var pi = Math.PI;
return degrees * (pi/180);
}
Then Math.sin(angleInRadians) would tell you the Y location of the spot where line intersects the circle, while Math.cos(angleInRadians) would tell you the X location. Both X and Y would be relative to the circle center.
And, since the result is for the unit circle, you would also have to multiply both X and Y with actual radius (250). And then add circle's center location (543,250) to get the actual world coordinates of the point.
X = (X * 250) + 543 and Y = (Y * 250) + 250
Hope that helped, you can use Google image search to get some sine and cosine drawings if you're not getting clear picture.
Formula:
x = R * cos(a1) = R * sqrt(1 - ((y + ∆y) / R)^2)
Solution:
let delta = 466.5 - 440.5;
let x = 250 * Math.sqrt(1 - Math.pow(466.5 + delta) / 250, 2));

Control object around sphere using quaternions

In my game the user controls an airplane (seen from the top), flying over the earth (a Sphere object). The airplane can rotate (steer) left or right (by pressing the LEFT or RIGHT arrow keys) and it can accelerate by pressing the UP arrow key. So the airplane always has a direction (rotation) and a certain speed (velocity) based on user input, stored in vx & vy variables.
In the render loop the vx & vy variables are used to rotate the globe. So the airplane does not actually move, it is the globe below the airplane that rotates to give the impression of the airplane flying over the earth.
This is all wonderful, until the player "reaches" the other side of the globe with his airplane. Now when the user flies "to the right" of the screen, the earth also rotates to the right, which makes it look that the airplane is flying backwards. The issue comes from trying to fit in some old 2D code of a previous airplane game of mine into this 3D game.
I would like to know how to solve this issue with quaternions. I am certain that I need those, but I just don't understand them fully. I figure that my vx and vy variables could still be useful for this, as they could make some kind of "new location" vector. From what I read is that I should normalize vectors, get an axis and an angle, but I am not sure of what and how to get these. Any help would be greatly appreciated!
Below is the code that rotates the earth when the user flies in a certain x/y direction plus an image to get a better picture of the game situation.
// AIRPLANE VARS
var friction = 0.85;
var vr = 7.5; // Rotate-velocity
var thrust = 0.5;
var max_speed = 20;
var vx = 0; // X-velocity
var vy = 0; // Y-velocity
// RENDER LOOP
function render() {
// check states
if (rotate_left) {
player.rotation.y = player.rotation.y + (vr * (Math.PI / 180));
} else if (rotate_right) {
player.rotation.y = player.rotation.y - (vr * (Math.PI / 180));
}
if(throttle){
//var radians = ((player.rotation.y * Math.PI) / 180);
var radians = player.rotation.y;
var ax = (Math.cos(radians) * thrust);
var ay = (Math.sin(radians) * thrust);
vx = vx + ax;
vy = vy + ay;
} else {
//ship.gotoAndStop(1);
vx = vx * friction;
vy = vy * friction;
}
// rotate the globe in the opposite direction of the airplane movement
globe.rotation.x = globe.rotation.x - (-vx/100);
globe.rotation.y = globe.rotation.y - (vy/100);
}
I am not familiar with your implementation framework, which appears from your tags to be three.js. It is also a bit difficult to see how your 'turn' controls affect the player, because you did not mention how the axes of the plane is defined. I may not be much help but I can give you some starting tips.
Firstly familiarise yourself with the structure of a quaternion and the implementation of it in three.js.
In many texts they appear as q = [w, x, y, z], however it seems in three.js they are defined as q = [x, y, z, w]. Don't worry too much about what those numbers are as they are very counter-intuitive to read.
There are a few ways to rotate the quaternion with respect to your velocity.
I think this is your best shot: rotate the quaternion by using the derivative equation given here, by calculating the angular velocity of the plane around the earth (and thus the earth around the plane). This is given by the 3D particle equation here. You can add the time-scaled derivative (dt*dqdt) to the quaternion q, then renormalise it in order to animate the rotation.
Another way is to pick a quaternion rotation that you want to end at, and use the slerp operation (built in to three.js).
If you give me some more details about how your sphere, plane and global frames are defined, I may be able to help more.

Algorithm for moving an object horizontally in javascript

I am currently working on a game using javascript and processing.js and I am having trouble trying to figure out how to move stuff diagonally. In this game, there is an object in the center that shoots other objects around it. Now I have no problem moving the bullet only vertically or only horizontally, however I am having difficulty implementing a diagonal motion for the bullet algorithm.
In terms of attempts, I tried putting on my math thinking cap and used the y=mx+b formula for motion along a straight line, but this is what my code ends up looking like:
ellipse(shuriken.xPos, shuriken.yPos, shuriken.width, shuriken.height); //this is what I want to move diagonally
if(abs(shuriken.slope) > 0.65) {
if(shuriken.targetY < shuriken.OrigYPos) {
shuriken.yPos -= 4;
} else {
shuriken.yPos += 4;
}
shuriken.xPos = (shuriken.yPos - shuriken.intercept)/shuriken.slope;
} else {
if(shuriken.targetX < shuriken.OrigXPos) {
shuriken.xPos -= 4;
} else {
shuriken.xPos += 4;
}
shuriken.yPos = shuriken.slope * shuriken.xPos + shuriken.intercept;
}
The above code is very bad and hacky as the speed varies with the slope of the line.
I tried implementing a trigonometry relationship but still in vain.
Any help/advice will be greatly appreciated!
Think of it this way: you want the shuriken to move s pixels. If the motion is horizontal, it should move s pixels horizontally; if vertical, s pixels vertically. However, if it's anything else, it will be a combination of pixels horizontally/vertically. What's the correct combination? Well, what shape do you get if you project s distance in any direction from a given point? That's right, a circle with radius s. Let's represent the direction in terms of an angle, a. So we have this picture:
How do we get the x and the y? If you notice, we have a triangle. If you recall your trigonometry, this is precisely what the sine, cosine, and tangent functions are for. I learned their definitions via the mnemonic SOHCAHTOA. That is: Sin (a) = Opposite/Hypotenuse, Cos(a) = Adjacent/Hypotenuse, Tan(a) = Opposite/Adjacent. In this case, opposite of angle a is y, and adjacent of angle a is x. Thus we have:
cos(a) = x / s
sin(a) = y / s
Solving for x and y:
x = s * cos(a)
y = s * sin(a)
So, given the angle a, and that you want to move your shuriken s pixels, you want to move it s * cos(a) horizontally and s * sin(a) vertically.
Just be sure you pass a in radians, not degrees, to javascript's Math.sin and Math.cos functions:
radians = degrees * pi / 180.0
This may be why your trigonometric solution didn't work as this has bitten me a bunch in the past.
If you know the angle and speed you are trying to move at, you can treat it as a polar coordinate, then convert to cartesian coordinates to get an x,y vector you would need to move the object by to go in that direction and speed.
If you don't know the angle, you could also come up with the vector by taking the difference in X and difference in Y (this I know you can do as you are able to calculate the slope between the 2 points). Then take the resulting vector and divide by the length of the vector to get a unit vector, which you can then scale to your speed to get a final vector in which you can move your object by.
(This is what probably what kennypu means by sticking with vectors?)

Calculate the direction based on degrees

So I'm working on a particle emitter with javascript and canvas.
And I want to be able to set what direction the particles are emitting based on an angle.
This can be done with this function:
y = Math.tan(45 * Math.PI/180);
Which returns 1 if the angle is 45. etc.
But I don't exacly know how I should implement this since pixels are calculated a little different. Think -1 as removing one pixel each step and 1 as adding one pixel.
If the angle is 45, Y is 1 and X is 1 which is correct.
But to get a pixel traveling at 315 degrees Y is -1 and X should be 1.
And at 225 degrees Y should be -1 (but is 1) and X should be -1.
How should the function look like if it should work like this?
Here is an image of how im thinking:
(The emitter is in the origin.)
Actually it's simple,
angle = (angle * Math.PI/180) % 360;
tangent = Math.tan(angle);
Since you do not know where is x;
section_x_positive = (angle<90||angle>270?1:-1);
section_y_positive = (angle>0&&angle<180?1:-1);
x = abs(tangent) * section_x_positive;
y = abs(tangent) * section_y_positive;
It sounds to me like your problem is that you're thinking about direction, which is a vector quantity, as if it were a scalar.
You need to remember that a 2D vector is represented as two components:
You can work in terms of unit vectors, so the magnitude r = 1.
So if you have a direction angle, which should be measured in radians, increasing in the counterclockwise direction, and starting at the x = 0 horizontal axis, you'll end up with two components of the unit vector that points in the direction you want.

Translating an element with canvas

I'm trying to learn canvas by implementing a pie chart. I've managed to parse my data, draw the slices, and calculate the center of each arc, as noted by the black circles. But now I'm trying to draw one of the slices as though it had been "slid out". Not animate it (yet), just simply draw the slice as though it had been slid out.
I thought the easiest way would be to first calculate the point at which the new corner of the slice should be (free-hand drawn with the red X), translate there, draw my slice, then translate the origin back. I thought I could calculate this easily, since I know the center of the pie chart, and the point of the center of the arc (connected with a free-hand black line on the beige slice). But after asking this question, it seems this will involve solving a system of equations, one of which is second order. That's easy with a pen and paper, dauntingly hard in JavaScript.
Is there a simpler approach? Should I take a step back and realize that doing this is really the same as doing XYZ?
I know I haven't provided any code, but I'm just looking for ideas / pseudocode. (jQuery is tagged in the off chance there's a plugin will somehow help in this endeavor)
Getting the x and y of the translation is easy enough.
// cx and cy are the coordinates of the centre of your pie
// px and py are the coordinates of the black circle on your diagram
// off is the amount (range 0-1) by which to offset the arc
// adjust off as needed.
// rx and ry will be the amount to translate by
var dx = px-cx, dy = py-cy,
angle = Math.atan2(dy,dx),
dist = Math.sqrt(dx*dx+dy*dy);
rx = Math.cos(angle)*off*dist;
ry = Math.sin(angle)*off*dist;
Plug that into the code Simon Sarris gave you and you're done. I'd suggest an off value of 0.25.
Merely translating an element on a canvas is very easy and there shouldn't be any tricky equations here. In the most basic sense it is:
ctx.save();
ctx.translate(x, y);
// Draw the things you want offset by x, y
ctx.restore();
Here's a rudimentary example of a square pie and the same pie with one of the four "slices" translated:
http://jsfiddle.net/XqwY2/
To make the pie piece "slide out" the only thing you need to calculate is how far you want it to be. In my simple example the blue block is slid out 10, -10.
If you are wondering merely how to get the X and Y you want in the first place, well, that's not quite a javascript/canvas question. For points on a line given a distance this question: Finding points on a line with a given distance seems the most clear
Edit, here you are (from comments):
// Center point of pie
var x1 = 100;
var y1 = 100;
// End of pie slice (your black dot)
var x2 = 200;
var y2 = 0;
// The distance you want
var distance = 3;
var vx = x2 - x1; // x vector
var vy = y2 - y1; // y vector
var mag = Math.sqrt(vx*vx + vy*vy); // length
vx = mag/vx;
vy = mag/vy;
// The red X location that you want:
var px = x1 + vx * ( distance);
var py = y1 + vy * ( distance);
This would give you a px,py of (104.24, 95.76) for my made-up inputs.

Categories

Resources