I'm trying to build an Augmented Reality Demonstration, like this iPhone App:
http://www.acrossair.com/acrossair_app_augmented_reality_nearesttube_london_for_iPhone_3GS.htm
However my geometry/math is a bit rusty nowadays.
This is what I know:
If i have my Android phone on the landscape mode (with the home button on the left), my z axis points to the direction I'm looking.
From the sensors of my phone i know what is the angle my z axis has with the North axis, let's call this angle theta.
If I have a vector from my current position to the point I want to show in my screen, i can calculate the angle this vector does with my z axis. Let's call this angle alpha.
So, based on the alpha angle I have a perception of where the point is, and I'm able to show it in the screen (like the Nearest Tube App).
This is the basic theory of a simple demonstration (of course it's nothing like the App, but it's the first step).
Can someone give me some lights on this matter?
[Update]
I've found this very interesting example, however I need to have the movement on both xx and yy axis. Any hints?
The basics are easy. You need the angle between your location and your destiny (arctangent), and the heading (from the digital compass in your phone). See this answer: Augmented Reality movement There is some objective-c code down there that you can read if you come from java.
What you want is a 3d-Space-Filling-Curve for example a hilbert-curve. That is a spatial index over 3 ccordinate. It is comparable to a octree. You want to store the object in that octree and do a depth-firat search on the coordinate you have recorded with your iphone as fixed coordinate probably the center of the screen. A octree subdivde the space continously in eigth directions and a 3d-Space-Filling-Curve is an hamiltonian path through the space which is like a fracta but it is clearly distinctable from the region of the octree. I use 2d-hilbert-curve to speed search in geospatial databases. Maybe you want to start with this first?
Related
I'm not sure if something like this has been asked but I've spent days trying to figure this out to no avail.
I've been working on a project that has a straight tube and a sleeve placed some length down the tube, this part of the problem isn't causing any issues but the orientation of the placed sleeve is. When the sleeve is placed it is given a location that intersects another object giving it all the information it needs to be placed, but I need that sleeve to orient itself with the tube, pretty much just along the roll axis, but I would like to hammer out how yaw and pitch would be done similarly.
The tube has transform data connected to it. It has an origin for the center point of the tube, and 3 xyz points standing for each basis axis. in example for one of the tubes tested:
origin:{(119.814557964, -37.330669765, 8.400185257)},
BasisX: {(1.000000000, 0.000000000, 0.000000000)},
BasisY: {(0.000000000, 0.939692621, 0.342020143)},
BasisZ: {(0.000000000, -0.342020143, 0.939692621)}.
In some of the solution parts I've come across I found some ways this information is used. And I've had some success with this way of doing it:
(note: I realize this code has a lot of pointless variable use, I didn't want to adjust it and confuse myself more)
upDownAxis = givenSleeveObject.passedOnTransform.BasisZ;
leftRightAxis = givenSleeveObject.passedOnTransform.BasisX;
tempOfVector = givenSleeveObject.passedOnTransform.OfVector(upDownAxis);//this ofvector is applying the transform to the vector
rotationAngle = upDownAxis.AngleOnPlaneTo(tempOfVector, leftRightAxis);
This was able to give me the angle rotation of this particular tube which was 20 degrees.
The problem is that this doesn't really work along the y axis the same, and completely wrong along the z axis. Likely due to after rotating to z axis the axis for each direction changes to one of the others at that angle. Also if it is of any help, the direction of the tube basically follows the basisX. If z is the only one with a 1, it is heading upward.
So now my issue is, how can I find the roll of this tube no matter it's orientation? Also rotation direction might matter in the long run. Since this object's transforms are all connected to itself, there must be a way to know how much of a roll has been done to it even at an extreme of 45 in every axis, right?
I have a complicated problem and it involves an understanding of Maths I'm not confident with.
Some slight context may help. I'm building a 3D train simulator for children and it will run in the browser using WebGL. I'm trying to create a network of points to place the track assets (see image) and provide reference for the train to move along.
To help explain my problem I have created a visual representation as I am a designer who can script and not really a programmer or a mathematician:
Basically, I have 3 shapes (Figs. A, B & C) and although they have width, can be represented as a straight line for A and curves (B & C). Curves B & C are derived (bend modified) from A so are all the same length (l) which is 112. The curves (B & C) each have a radius (r) of 285.5 and the (a) angle they were bent at was 22.5°.
Each shape (A, B & C) has a registration point (start point) illustrated by the centre of the green boxes attached to each of them.
What I am trying to do is create a network of "track" starting at 0, 0 (using standard Cartesian coordinates).
My problem is where to place the next element after a curve. If it were straight track then there is no problem as I can use the length as a constant offset along the y axis but that would be boring so I need to add curves.
Fig. D. demonstrates an example of a possible track layout but please understand that I am not looking for a static answer (based on where everything is positioned in the image), I need a formula that can be applied no matter how I configure the track.
Using Fig. D. I tried to work out where to place the second curved element after the first one. I used the formula for plotting a point of the circumference of a circle given its centre coordinates and radius (Fig. E.).
I had point 1 as that was simply a case of setting the length (y position) of the straight line. I could easily work out the centre of the circle because that's just the offset y position, the offset of the radius (r) (x position) and the angle (a) which is always 22.5° (which, incidentally, was converted to Radians as per formula requirements).
After passing the values through the formula I didn't get the correct result because the formula assumed I was working anti-clockwise starting at 3 o'clock so I had to deduct 180 from (a) and convert that to Radians to get the expected result.
That did work and if I wanted to create a 180° track curve I could use the same centre point and simply deducted 22.5° from the angle each time. Great. But I want a more dynamic track layout like in Figs. D & E.
So, how would I go about working point 5 in Fig. E. because that represents the centre point for that curve segment? I simply have no idea.
Also, as a bonus question, is this the correct way to be doing this or am I over-complicating things?
This problem is the only issue stopping me from building my game and, as you can appreciate, it is a bit of a biggie so I thank anyone for their contribution in advance.
As you build up the track, the position of the next piece of track to be placed needs to be relative to location and direction of the current end of the track.
I would store an (x,y) position and an angle a to indicate the current point (with x,y starting at 0, and a starting at pi/2 radians, which corresponds to straight up in the "anticlockwise from 3-o'clock" system).
Then construct
fx = cos(a);
fy = sin(a);
lx = -sin(a);
ly = cos(a);
which correspond to the x and y components of 'forward' and 'left' vectors relative to the direction we are currently facing. If we wanted to move our position one unit forward, we would increment (x,y) by (fx, fy).
In your case, the rule for placing a straight section of track is then:
x=x+112*fx
y=y+112*fy
The rule for placing a curve is slightly more complex. For a curve turning right, we need to move forward 112*sin(22.5°), then side-step right 112*(1-cos(22.5°), then turn clockwise by 22.5°. In code,
x=x+285.206*sin(22.5*pi/180)*fx // Move forward
y=y+285.206*sin(22.5*pi/180)*fy
x=x+285.206*(1-cos(22.5*pi/180))*(-lx) // Side-step right
y=y+285.206*(1-cos(22.5*pi/180))*(-ly)
a=a-22.5*pi/180 // Turn to face new direction
Turning left is just like turning right, but with a negative angle.
To place the subsequent pieces, just run this procedure again, calculating fx,fy, lx and ly with the now-updated value of a, and then incrementing x and y depending on what type of track piece is next.
There is one other point that you might consider; in my experience, building tracks which form closed loops with these sort of pieces usually works if you stick to making 90° turns or rather symmetric layouts. However, it's quite easy to make tracks which don't quite join up, and it's not obvious to see how they should be modified to allow them to join. Something to bear in mind perhaps if your program allows children to design their own layouts.
Point 5 is equidistant from 3 as 2, but in the opposite direction.
I'm working on an FPS with the jPCT library. One key thing that all FPS's need is to prevent the players from looking behind them by pulling the mouse too far up/down. Currently, I'm using some example code found on the jPCT's website that keeps track of how many angles have been added to the camera, but I'm worried about rounding issues with all the angles in radians. I can get a rotation Matrix from jPCT's camera, and I know that it contains the information to figure out how "high" up the player is looking, but I have no clue how to get it out of the matrix.
What would I look for in the rotation matrix that will tell me if the player is looking more "up" than strait up and more "down" than strait down?
If you're updating your matrix each time the player moves you're going to run into trouble due to floating point errors and your rotation matrix will turn into a skew matrix. One solution is to orthonormalise the matrix every now and then but usually it's better to simply keep the player's pitch, yaw (and roll if you need it) as floats and build your matrix from those angles when the player changes orientation, looks up/down etc. If you use optimised code for each angle (or a single method for converting Euler angles to a matrix) it's not slower than what you seem to be doing right now. You won't run into Gimbal lock issues as the camera orientation will be restricted anyway.
As for your specific question I think you'd need to calculate the angle between matrix Z axis (the third row or column, depends how your matrices are oriented) and an unrotated vector pointing down your Z axis.
I'm making a side scroller similar to Castle Crashers and right now I'm using SAT for collision detection. That works great, but I want to simulate level "depth" by allowing objects to move up and down on the screen, basically along a z-axis (like this screenshot http://favoniangamers.files.wordpress.com/2009/07/castle-crashers-ps3.jpg). This isn't an isometric game, but rather uses parallax scrolling.
I added a z component to my vector class, and I plan to cull collisions based on the 'thickness' of a shape and it's z position. I'm just not sure how calculate the positions of shapes for rendering or how to add jumping with gravity. How do I calculate the max y value (for the ground) as the z position changes? Basically it's the relationship of the z and y axis that confuses me.
I'd appreciate links to resources if anyone knows of this topic.
Thanks!
It's actually possible to make your collision detection algorithm dimensionally agnostic. Just have a collision detector that works along one dimension, use that to check each dimension, and your answer to "are these colliding or not" is the logical AND of the collision detection along each of the dimensions.
Your game should be organised to keep the interaction of game objects, and the rendering of the game to the screen completely seperate. You can think of these two sections of the program as the "model" and the "view". In the model, you have a full 3D world, with 3 axes. You can't go halvesies on this point without some level of pain. Your model must be proper 3D.
The view will read the location of all the game objects, and project them onto the screen using the camera definition. For this part you don't need a full 3D rendering engine. The correct technical term for the perspective you're talking about is "oblique", and it can be seen in many ancient chinese and japanese scroll paintings and prints- in particular look for images of "The Tale of Genji".
The on screen position of an object (including the ground surface!) goes something like this:
DEPTH_RATIO=0.5;
view_x=model_x-model_z*DEPTH_RATIO-camera_x;
view_y=model_y+model_z*DEPTH_RATIO-camera_y;
you can modify for a straight orthographic front projection:
DEPTH_RATIO=0.5;
view_x=model_x-camera_x;
view_y=model_y+model_z*DEPTH_RATIO-camera_y;
And of course don't forget to cull objects outside the volume defined by the camera.
You can also use this mechanism to handle the positioning of parallax layers for you. This is of course, a matter changing your camera to a 1-point perspective projection instead of an orthographic projection. You don't have to use this to change the rendered size of your sprites, but it will help you manage the x position of objects realistically. if you're up for a challenge, you could even mix projections- use 1 point perspective for deep backgrounds, and the orthographic stuff for the foreground.
You should separate your conceptual Y axis used by you physics calculation (collision detection etc.) and the Y axis you actually draw on the screen. That way it becomes less confusing.
Just do calculations per normal pretending there is no relationship between Y and Z axis then when you actually draw the object on the screen you simulate the Z axis using the Y axis:
screen_Y = Y + Z/some_fudge_factor;
Actually, this is how real 3d engines work. After all the world calculations are done the X, Y and Z coordinates are mapped onto screen_X and screen_Y via a function (usually a bit more complicated than the equation above, but just a bit).
For example, to implement pseudo-isormetric view in your game you can even apply Z to the screen_X axis so objects are displaced diagonally instead of vertically.
I'm an artist involved with building various sorts of computer controlled machines. I've started prototyping a gimble-based XY painting machine and have realized that the maths needed are out of my reach. I'm a decent enough programmer but not strong in math- esp. 3D math.
To get a sense of what I'm needing to do, it might be helpful to look at the rig:
Early prototype:
http://roypardi.com/gimble/gimbleSmall.MOV (small video)
http://roypardi.com/gimble/gimbleLarge.mov (larger video)
The two inner rings represent the X/Y axes and are controlled by stepper motors. I want to be able to use both raster images and vector data (gcode). So I need to be able to address a point in 2D space on the paper/from my data and have the gimble figure out what orientation it needs to be at in order to get there (i.e. how much to step each motor).
I've been searching out 2D > 3D projection, Euler angles, etc. but I'm out of my depth. Any pointers, pushes in the right direction, or code snippets would be most welcome. I can make sense of most programming languages.
Very nice machine you have made, I hope this works for you I believe it is correct.
The way I see it, is to get one angle is simple, but the other is slightly harder to visualise as we have tilted the axis which it turns upon.
I'm going to avoid using tan, as when programming this could result in a division by 0, which could be frustrating. Also Z is going to be the height of the origin above the paper.
YAxis = arcsin( X / sqrt(X² + Z²))
XAxis = arcsin( Y / sqrt(Y² + X² + Z²))
or we could use
XAxis = arcsin(Y / sqrt(Y² + Z²))
YAxis = arcsin( X / sqrt(X² + Y² + Z²))
Also, I'd very much like to see a video of this plotting, if it works.
Edit:
After thinking about it i believe only one solution will work it depends on which axis is affected by the other. Is the YAxis in the Middle or the Xaxis?
I think it's a problem of simple http://en.wikipedia.org/wiki/Trigonometry
Let's say that the distance from the centre of your rings to the nearest point on the paper (which I'll call point 'O' for 'Origin') is distance X.
Take another point P directly north of O, whose distance from O is Y.
To paint this point, you need the angle alpha such that tan(alpha)=Y/X, i.e. you can calculate alpha using the formula "arctan(Y/X)" [arctan is sometimes also known as atan]. Arctan is a trignometric function, which I think you'll probably find defined in the API of a general purpose math library.
The above is the simplest case.
The only other case that I can think of is when the point P isn't due north. Instead of being due north, let's say that its distance is Y1 to the north, and Y2 to the east. The solution is two angles (one angle for each of two rings), one of which is "arctan(Y1/X)" and the other of which is "arctan(Y2/X)".
Perhaps I misunderstand, but I don't believe a gimbal will do what you want. A gimbal can point in any 3D direction, but it cannot move to arbitrary points in 3D space. If the plane of the paper intersects the volume swept by the pen held in the gimbal, the pen might be able to draw a circle, but nothing more. Even drawing a circle is not a sure thing, since in this case the paper would also intersect the volume swept by the gimbal rings; trying to orient the pen would make a ring hit the paper.
I think what you want is a plotter, not a gimbal.