How can we use vector and scalar in games? What benefit from that.
Could someone please indicate precisely the difference between a scalar and a vector in games field ? I find no matter how many times I try to understand but I maybe need examples for that.
A scalar is just another word for a number. The distinction is that a scalar is a number that is part of a vector. There is nothing special about a scalar.
A vector is a set of numbers (one or more) that define something, in the most common case you have 2 numbers representing a 2D vector or 3 numbers representing a 3D vector. The abstract notion for a vector is simply an arrow.
Take a piece of graph paper. Select any point on that paper and call it the origin. Its coordinate will be x = 0, y = 0. Now draw a straight line from that point in any direction and any length. To describe that arrow you need to define the vector. Count how far across the page the end of the arrow is from the start (origin) and that is the x component. Then how far up the page and that is the y component.
You have just created a vector that has two numbers (x,y) that completely describe the arrow on the paper. This type of vector always starts at zero. You can also describe the vector by its direction (ie north, east, south...) and length.
In 3D you need 3 numbers to describe any arrow. (x,y,z)
Vectors are very handy. You can use a vector to describe how fast something is moving and in what direction. The vector represents a little arrow that starts where the object is now and ends where the object will be in the next time unit.
Thus an object at coordinate x,y has a vector velocity(0.2,0.3). To calculate the position of the object in the next time unit just add the vector to the coordinate
newXPos = currentXPos + velocityVectorX
newYPos = currentYPos + velocityVectorY
If you want to slow the speed by half you can multiply the vector by 0.5
velocityVectorX = velocityVectorX * 0.5
velocityVectorY = velocityVectorY * 0.5
You do the same to increase the speed.
velocityVectorX = velocityVectorX * 2
velocityVectorY = velocityVectorY * 2
You may have an object in 3D space that has many forces acting on it. There is gravity a vector (arrow) pointing down (G). The force of the air resistance pointing up (R). The current velocity another arrow pointing in the direction it is traveling (V). You can have as many as you like (need) to describe all the forces that push and pull at the object. When you need to calculate the position of the object for the next instance in time (say one second) you just add all the force vectors together to get the total force as a vector and add that to the objects position
Object.x = Object.x + G.x + R.x + V.x;
Object.y = Object.y + G.y + R.y + V.y;
Object.z = Object.z + G.y + R.z + V.z;
If you just want the velocity
V.x = V.x + G.x + R.x;
V.y = V.y + G.y + R.y;
V.z = V.z + G.y + R.z;
That is the new velocity in one second.
There are many things that can be done with a vector. A vector can be used to point away from a surface in 3D, this vector is called a surface normal. The you create a vector from a point on that surface pointing to a light. The cosine of the angle between the two vectors is how much light the surface will reflect.
You can use a vector to represent the three direction in space an object has. Say a box, there is a 3D vector pointing along the width, another along the height and the last along the depth. The length of each vector represents the length of each side. You can make another vector to represent how far the corner of the box is from the origin (any known point) In 3D these 4 vectors are used to represent the object and is called a transformation matrix (just another type of vector made up of vectors)
The list of things vectors can do is endless.
The basics is just like number, you can add, subtract, multiply and divide and vector.
Then there are a host of special functions for vectors, normalize, transform, dot product and cross product to name but a few. For these things people normally use a library that does all this for you. My view is that if you really want to learn about vectors and how they are used write your own vector library at some point until then use a library.
Hope that cleared the mud a little bit for you, it is always difficult to describe something you have used for a long time to someone that is new to it so feel free to ask questions in the comments if you need.
Related
Perhaps the question title needs some work.
For context this is for the purpose of a Koch Snowflake (using C-like math syntax in a formula node in LabVIEW), thus why the triangle must be the correct way. (As given 2 points an equilateral triangle may be in one of two directions.)
To briefly go over the algorithm: I have an array of 4 predefined coordinates initially forming a triangle, the first "generation" of the fractal. To generate the next iteration, one must for each line (pair of coordinates) get the 1/3rd and 2/3rd midpoints to be the base of a new triangle on that face, and then calculate the position of the 3rd point of the new triangle (the subject of this question). Do this for all current sides, concatenating the resulting arrays into a new array that forms the next generation of the snowflake.
The array of coordinates is in a clockwise order, e.g. each vertex travelling clockwise around the shape corresponds to the next item in the array, something like this for the 2nd generation:
This means that when going to add a triangle to a face, e.g. between, in that image, the vertices labelled 0 and 1, you first get the midpoints which I'll call "c" and "d", you can just rotate "d" anti-clockwise around "c" by 60 degrees to find where the new triangle top point will be (labelled e).
I believe this should hold (e.g. 60 degrees anticlockwise rotating the later point around the earlier) for anywhere around the snowflake, however currently my maths only seems to work in the case where the initial triangle has a vertical side: [(0,0), (0,1)]. Else wise the triangle goes off in some other direction.
I believe I have correctly constructed my loops such that the triangle generating VI (virtual instrument, effectively a "function" in written languages) will work on each line segment sequentially, but my actual calculation isn't working and I am at a loss as to how to get it in the right direction. Below is my current maths for calculating the triangle points from a single line segment, where a and b are the original vertices of the segment, c and d form new triangle base that are in-line with the original line, and e is the part that sticks out. I don't want to call it "top" as for a triangle formed from a segment going from upper-right to lower-left, the "top" will stick down.
cx = ax + (bx - ax)/3;
dx = ax + 2*(bx - ax)/3;
cy = ay + (by - ay)/3;
dy = ay + 2*(by - ay)/3;
dX = dx - cx;
dY = dy - cy;
ex = (cos(1.0471975512) * dX + sin(1.0471975512) * dY) + cx;
ey = (sin(1.0471975512) * dX + cos(1.0471975512) * dY) + cy;
note 1.0471975512 is just 60 degrees in radians.
Currently for generation 2 it makes this: (note the seemingly separated triangle to the left is formed by the 2 triangles on the top and bottom having their e vertices meet in the middle and is not actually an independent triangle.)
I suspect the necessity for having slightly different equations depending on weather ax or bx is larger etc, perhaps something to do with how the periodicity of sin/cos may need to be accounted for (something about quadrants in spherical coordinates?), as it looks like the misplaced triangles are at 60 degrees, just that the angle is between the wrong lines. However this is a guess and I'm just not able to imagine how to do this programmatically let alone on paper.
Thankfully the maths formula node allows for if and else statements which would allow for this to be implemented if it's the case but as said I am not awfully familiar with adjusting for what I'll naively call the "quadrants thing", and am unsure how to know which quadrant one is in for each case.
This was a long and rambling question which inevitably tempts nonsense so if you've any clarifying questions please comment and I'll try to fix anything/everything.
Answering my own question thanks to #JohanC, Unsurprisingly this was a case of making many tiny adjustments and giving up just before getting it right.
The correct formula was this:
ex = (cos(1.0471975512) * dX + sin(1.0471975512) * dY) + cx;
ey = (-sin(1.0471975512) * dX + cos(1.0471975512) * dY) + cy;
just adding a minus to the second sine function. Note that if one were travelling anticlockwise then one would want to rotate points clockwise, so you instead have the 1st sine function negated and the second one positive.
I have two 3D vectors called A and B that both only have a 3D position. I know how to find the angle along the unit circle ranging from 0-360 degrees with the atan2 function by doing:
EDIT: (my atan2 function made no sense, now it should find the "y-angle" between 2 vectors):
toDegrees(atan2(A.x-B.x,A.z-B.z))+180
But that gives me the Y angle between the 2 vectors.
I need to find the X angle between them. It has to do with using the x, y and z position values. Not the x and z only, because that gives the Y angle between the two vectors.
I need the X angle, I know it sounds vague but I don't know how to explain. Maybe for example you have a camera in 3D space, if you look up or down than you rotate the x-axis. But now I need to get the "up/down" angle between the 2 vectors. If I rotate that 3D camera along the y-axis, the x-axis doens't change. So with the 2 vectors, no matter what the "y-angle" is between them, the x-angle between the 2 vectors wil stay the same if y-angle changes because it's the "up/down" angle, like in the camara.
Please help? I just need a line of math/pseudocode, or explanation. :)
atan2(crossproduct.length,scalarproduct)
The reason for using atan2 instead of arccos or arcsin is accuracy. arccos behaves very badly close to 0 degrees. Small computation errors in argument will lead to disproportionally big errors in result. arcsin has same problem close to 90 degrees.
Computing the altitude angle
OK, it might be I finally understood your comment below about the result being independent of the y angle, and about how it relates to the two vectors. It seems you are not really interested in two vectors and the angle between these two, but instead you're interested in the difference vector and the angle that one forms against the horizontal plane. In a horizontal coordinate system (often used in astronomy), that angle would be called “altitude” or “elevation”, as opposed to the “azimuth” you compute with the formula in your (edited) question. “altitude” closely relates to the “tilt” of your camera, whereas “azimuth” relates to “panning”.
We still have a 2D problem. One coordinate of the 2D vector is the y coordinate of the difference vector. The other coordinate is the length of the vector after projecting it on the horizontal plane, i.e. sqrt(x*x + z*z). The final solution would be
x = A.x - B.x
y = A.y - B.y
z = A.z - B.z
alt = toDegrees(atan2(y, sqrt(x*x + z*z)))
az = toDegrees(atan2(-x, -z))
The order (A - B as opposed to B - A) was chosen such that “A above B” yields a positive y and therefore a positive altitude, in accordance with your comment below. The minus signs in the azimuth computation above should replace the + 180 in the code from your question, except that the range now is [-180, 180] instead of your [0, 360]. Just to give you an alternative, choose whichever you prefer. In effect you compute the azimuth of B - A either way. The fact that you use a different order for these two angles might be somewhat confusing, so think about whether this really is what you want, or whether you want to reverse the sign of the altitude or change the azimuth by 180°.
Orthogonal projection
For reference, I'll include my original answer below, for those who are actually looking for the angle of rotation around some fixed x axis, the way the original question suggested.
If this x angle you mention in your question is indeed the angle of rotation around the x axis, as the camera example suggests, then you might want to think about it this way: set the x coordinate to zero, and you will end up with 2D vectors in the y-z plane. You can think of this as an orthogonal projection onto said plain. Now you are back to a 2D problem and can tackle it there.
Personally I'd simply call atan2 twice, once for each vector, and subtract the resulting angles:
toDegrees(atan2(A.z, A.y) - atan2(B.z, B.y))
The x=0 is implicit in the above formula simply because I only operate on y and z.
I haven't fully understood the logic behind your single atan2 call yet, but the fact that I have to think about it this long indicates that I wouldn't want to maintain it, at least not without a good explanatory comment.
I hope I understood your question correctly, and this is the thing you're looking for.
Just like 2D Vectors , you calculate their angle by solving cos of their Dot Product
You don't need atan, you always go for the dot product since its a fundamental operation of vectors and then use acos to get the angle.
double angleInDegrees = acos ( cos(theta) ) * 180.0 / PI;
I am having readings of Yaw, pitch, Roll, Rotation matrix, Quaternion and Acceleration. These reading are taken with frequency of 20 (per second). They are collected from the mobile device which is moving in 3D space from one position to other position.
I am setting reference plane by multiplying inverse matrix to the start postion. The rest of the readings are taken by considering the first one as a reference one. Now I want to convert these readings to 3D cartesian system.
How to convert it? Can anyone please help?
Ok basically yaw, pitch and roll are the euler angles, with them you got your rotation matrix already.
Quaternions are aquivalent to that, with them you can also calculate the rotation matrix you need.
If you have rotation matrices R_i for every moment i in your l=20secs interval. Than these rotations are relative the the one applied at R_(i-1) you can calculate their rotation relative to the first position. So A_i = R_1*...*R_i but after all you could also just safe the new direction of travel (safes calculations).
So asuming that the direction of travel is d_0 = (1,0,0) at first. You can calculate the next by d_i = R_i*d_(i-1) (always norm d_(i-1) because it might get smaller or bigger due to error). The first position is p and your start speed is v_0 = (0,0,0) and finally the acceleration is a_i. You need to calculate the vectorial speed v_i for every moment:
v_i = v_(i-1) + l*a_i*A_i*d_0 = v_(i-1) + l*a_i*d_i
Now you basically know where you are moving, and what kind of speed you use, so your position p_i at the moment i is given by:
`p_i = p_0 + l * ( v_1 + v_2 + ... + v_i)`
For the units:
a_i = [m/s^2]^3
v_i = [m/s]^3
p_i = [m]^3
Precision
Now some points to the precision of your position calculation (just if you want to know how good it will work). Suppose you have an error e>= ||R_i*v-w|| (where w is the correct vector). in the data you calculate the rotation matrices with. Your error is multipling itself so your error in the i moment is e_i <= e^i.
Then because you apply l and a_i to it, it becomes:
f_i <= l*a_i*e^i
But you are also adding up the error when you add up the speed, so now its g_i <= f_1+...+f_i. And yeah you also add up for the position (both sums over i):
h_i <= g_1+...+g_i = ΣΣ (l*a_i*e^i) = l* ΣΣ (a_i*e^i)
So this is basically the maximum difference from your position p_i to the correct position w (||p_i - w|| <= h_i).
This is still not taking in account that you don't get the correct acceleration from your device (I don't know how they normally do this), because correct would be:
a_i = ||∫a_i(t) dt|| (where a_i(t) is vectorial now)
And you would need to calculate the difference in direction (your rotation matrix) as:
Δd_i = (∫a_i(t) dt)/a_i (again a_i(t) is vectorial)
So apart from the errors you get from the error in your rotations from your device (and from floating point arithmetic), you have an error in your acceleration, I won't calculate that now but you would substitute a_i = a_i + b_i.
So I'm pretty sure it will be far off from the real position. You even have to take in account that you're speed might be non zero when it should be!
But that beeing said, I would really like to know the precision you get after implementing it, that's what always keept me from trying it.
I want to know how to measure the distance between two pixels in dicom . already done some google found pixel spacing (0028,0030) need to find the distance . could some one clearly explain ....
thanks
Assuming that you're trying to measure distances in the subject/animal/phantom/whatever, it all depends on whether you want to measure distances between different slices or just in the same slice.
Volumetric DICOM series typically have a slice spacing (0012,0088) in addition to the pixel spacing which you need to take into account. Note that there is also such a thing as slice thickness, which is distinct and should not be used for calculating distances, as there can be a gap or overlap between consecutive slices.
It is helpful to define a voxelspacing vector as follows (pseudocode):
voxelspacing.x = first element of PixelSpacing (0028,0030), i.e. before "\"
voxelspacing.y = second element of PixelSpacing (0028,0030), i.e. after "\"
voxelspacing.z = SliceSpacing (0018,0088) or 0 if 2D and/or not specified
Some brain-dead manufacturers and de-identification tools break the slice spacing tag in which case you'll have to calculate it from another source, such as difference in consecutive slice location, patient image position, etc, but that's another matter.
Moving on, you now have the distance in millimeters between voxels for each dimension. You can then calculate the real-world euclidean distance given voxel coordinates in pointA and pointB:
delta = (pointA - pointB) * voxelspacing
distance = sqrt(delta.x^2 + delta.y^2 + delta.z^2);
Where all the operators are element-wise. It is critical to individually multiply the voxel coordinates with their respective spacings before computing distance, because voxels are typically not isotropic.
You need to know the dot pitch of the monitor. For example a jumbotron has huge pixels (guessing), so the distance is larger than it would be for a typical desktop monitor. Ask the manufacturer of the monitor for this information. After that use pythogorean theorum. sqrt(a^2 + b^2) = c c being the total distance and a/b are x and y distances. to find a and be you would find the coordinates of one pixel and subtract from the other. a = (x1-x2) b = (
Hello all math masters, I got a problem for you:
I have a 2D game (top down), and I would like to make the character escape from a shot, but not just walk away from the shot (I mean, don't be pushed by the shot), I want it to have a good dodging skills.
The variables are:
shotX - shot x position
shotY - shot y position
shotSpeedX - shot x speed
shotSpeedY - shot x speed
charX - character x position
charY - character y position
keyLeft - Set to true to make the character press the to left key
keyRight - Set to true to make the character press the to right key
keyUp - Set to true to make the character press the to up key
keyDown - Set to true to make the character press the down key
I can understand the following languages:
C/C++
Java
Actionscript 2/3
Javascript
I got this code (Actionscript 3), but sometimes it doesn't work:
var escapeToLeft:Boolean = false;
var r:Number = Math.atan2(0 - shotSpeedY, 0 - shotSpeedX)
var angle:Number = Math.atan2(charY - (shotY + shotSpeedY), charX - (shotX + shotSpeedX));
var b:Number = diepix.fixRotation(r-angle); // This function make the number between -180 and 180
if(b<0) {
escapeToLeft = true;
}
r += (escapeToLeft?1:0 - 1) * Math.PI / 2;
var cx:Number = Math.cos(r);
var cy:Number = Math.sin(r);
if(cx < 0.0) {
keyLeft = true;
}else {
keyRight = true;
}
if(cy < 0.0) {
keyUp = true;
}else {
keyDown = true;
}
Some observations:
Optimal dodging probably involves moving at a 90 degree angle from the bullets direction. That way, you get out of harms way the quickest.
If you do err, you want to err in the direction of the bullet, as that buys you time.
you can calculate 90 degrees to bullet direction with the scalar product
find the closest compass direction to the calculated optimal angle (4 possible answers)
are you allowed to go up and left at the same time? Now you have 8 possible answers to a bullet
bonus points for dodging in optimal direction according to second point
The scalar product of two vectors (ax, ay) and (bx, by) is ax * bx + ay * by. This is 0 if they are orthogonal (90 degrees). So, given the bullet (ax, ay), find a direction (bx, by) to run that has a scalar product of 0:
ax * bx must equal ay * by, so (bx, by) = (-ax, -ay)
Now to find the closest point on the compass for (bx, by), the direction you would like to run to. You can probably figure out the technique from the answer to a question of mine here on SO: How to "snap" a directional (2D) vector to a compass (N, NE, E, SE, S, SW, W, NW)? (note, thow, that I was using a wonky coordinate system there...)
If you have only 4 compass directions, your easiest path is to take:
max(abs(bx), abs(by))
The bigger vector component will show you the general direction to go - for
bx positive: right
bx negative: left
by positive: up (unless (0, 0) is top left with y positive in bottom left...)
by negative: down
I guess you should be able to come up with the rest on your own - otherwise, good luck on writing your own game!
I am not following what the line
var angle:Number = Math.atan2(charY - (shotY + shotSpeedY), charX - (shotX + shotSpeedX));
is supposed to be doing. The vector ( charY - shotY, charX - shotX ) would be the radius vector pointing from the location of the shot to the location of the character. But what do you have when you subtract a speed vector from that, as you are doing in this line?
It seems to me that what you need to do is:
Calculate the radius vector (rY, rX) where rY = shotY - charY; rX = xhotX - charX
Calculate the optimal direction of jump, if the character weren't constrained to a compass point.
Start with a vector rotated 90 degrees from the shot-character radius vector. Say vJump = ( rX, -rY ). (I think Daren has this calculation slightly wrong--you are transposing the two coordinates, and reversing one of their signs.)
The character should either wants to jump in the direction of vJump or the direction of -vJump. To know which, take the scalar product of vJump with (shotSpeedY, shotSpeedX). If this is positive, then the character is jumping towards the bullet, which you don't want, obviously, so reverse the sign of both components of vJump in this case.
Jump in the permissible direction that is closest to vJump. In the code you listed, you are constrained to jump in one of the diagonal directions--you will never jump in one of the cardinal directions. This may in fact be the mathematically optimal solution, since the diagonal jumps are probably longer than the cardinal jumps by a factor of 1.414.
If your jumps are actually equal distance, however, or if you just don't like how it looks if the character always jumps diagonally, you can test each of the eight cardinal and intermediate directions by calculating the scalar product between vJump and each of the eight direction vectors (0,1), (0.7071,0.7071), (1,0), (0.7071,-0.7071), etc. Take the direction that gives you the biggest positive scalar product. Given the patterns present, with some clever programming you can do this in fewer than eight tests.
Note that this algorithm avoids any math more complicated than addition and multiplication, so will likely have much better performance than something that requires trig functions.