I'm creating android app, I'm going to build dialer, and spin the dialer. If the arrow intersect with the specific layer, it will pop out the result. I'm using sliced dialer into many layers, each layer represent different data and I have one arrow, pointing to the layer. This arrow is going to intersect with either one layer. I want to make the arrow calculate the percentage of overlapping among the layers so that the arrow can determine which it's pointing to. This is just my whole picture of doing it. Any suggestions or improvements ? BTW, how to calculate images overlapping percentage ?
I'd recommend keeping track the angle of the arrow and using that to calculate which section it is on. You should have the angle since you probably need it to draw the arrow. With the angle, it is quite simple to calculate which section it is on.
The code would look something like this:
public static final int TOTAL_DEGREES = 360;
public int calculateSelectedSection(float degrees, int numSections) {
return (int) (degrees / TOTAL_DEGREES * numSections);
}
Related
I want to launch projectiles from the bottom-right corner of the screen towards the left side of the screen. Now, I want the projectiles to fly with random velocities and angles according to the screen dimensions, just like that. Now, I know this is very simple but from some reason I can't manage to make this work.
Here is what I have tried so far:
My first try - Launch function
private void launchProjectile() {
projectiles.peek().getBody().applyForce(projectiles.peek().getBody().getWorldVector(new Vector2(MathUtils.random(-20,-1*SCALAR_HEIGHT),
MathUtils.random(2*SCALAR_HEIGHT,8*SCALAR_HEIGHT)).scl(MathUtils.random(3*SCALAR_HEIGHT,5*SCALAR_HEIGHT))),
projectiles.peek().getBody().getWorldCenter(), true);
Gdx.app.log("System", String.valueOf(SCALAR_HEIGHT));
}
Here is my second try - Launch function
private void launchProjectile() {
float xVelocity;
float yVelocity;
xVelocity = (float) MathUtils.random(0,0)*SCALAR_WIDTH/2;
yVelocity = (float) MathUtils.random(20,20)*SCALAR_HEIGHT;
velocityProjectile.set(xVelocity,yVelocity); // Sets the velocity vector to the above values
velocityProjectile.sub(projectiles.peek().getBody().getPosition());
velocityProjectile.nor(); // Normalize the vector - Now it's fine and ready!
// Sets the start velocity of the projectile Trajectory to the current velocity
projectiles.peek().getBody().setLinearVelocity(velocityProjectile.scl(18+SCALAR_HEIGHT));
}
In both tries, the projectile flies way more than I need and it doens't take in consideration the screen size like it should.
Can you guys please tell me what is the right way to do this?
Thanks!!
Start with this page: http://www.iforce2d.net/b2dtut/projected-trajectory
In the "How fast should it be launched to reach a desired height?" section, you can see how much vertical velocity will be required to make the projectile reach the top of the screen. So you would pick a random number less than that, to make sure it doesn't go off the top of the screen.
Next, in the "How high will it go?" section, you can see the formula to find out how many time steps it will take for the projectile to reach maximum height. It will then take the same amount of time to come back down to the starting height. For example, let's say it would take 60 time steps to reach maximum height. That means it would take 120 time steps to fall down again to the same height as it started. Then you can set the horizontal part of the launch velocity so that it cannot go outside the screen in 120 time steps.
I am making a java program that classifies a set of lat/lng coordinates to a specific rectangle of a custom size, so in effect, map the surface of the earth into a custom grid and be able to identify what rectangle/ polygon a point lies in.
The way to do this I am looking into is by using a map projection (possibly Mercator).
For example, assuming I want to classify a long/lat into 'squares' of 100m x 100m,
44.727549, 10.419704 and 44.727572, 10.420460 would classify to area X
and
44.732496, 10.528092 and 44.732999, 10.529465 would classify to area Y as they are within 100m apart.
(this assumes they lie within the same boundary of course)
Im not too worried about distortion as I will not need to display the map, but I do need to be able to tell what polygon a set of coordinates belong to.
Is this possible? Any suggestions welcome. Thanks.
Edit
Omitting projection of the poles is also an acceptable loss
Here is my final solution (in PHP), creates a bin for every square 100m :
function get_static_pointer_table_id($lat, $lng)
{
$earth_circumference = 40000; // km
$lat_bin = round($lat / 0.0009);
$lng_length = $earth_circumference * cos(deg2rad($lat));
$number_of_bins_on_lng = $lng_length * 10;
$lng_bin = round($number_of_bins_on_lng * $lng / 360);
//the 'bin' unique identifier
return $lat_bin . "_" . $lng_bin;
}
If I understand correctly, you are looking for
a way to divide the surface of the earth into approximately 100m x 100m squares
a way to find the square in which a point lies
Question 1 is mission impossible with squares but much less so with polygons. A very simple way to create the polygons would to use the coordinates themselves. If each polygon is 0.0009° in latitude and longitude, you will have approximately square 100m x 100m grid on the equator, put the slices will become very thin close to the poles.
Question 2 depends on the approximation used to solve the challenge outlined above. If you use the very simple method above, then placing each coordinate into a bin is just a division by 0.0009 (and rounding down to the closest integer).
So, first you will have to decide what you can compromise. Is it important to have equal area in the polygons, equal longitudinal distance, equal latitude distance, etc.? Is it important to have four corners in the polygon? Is it important to have similar or almost similar polygons close to the poles and close to the equator? Once you know the limitations set by your application, choosing the projection becomes easier.
What you are trying to do here is a projection onto a flat surface of an ellipsoid. So as long as your points are close together, and, well, you don't mind getting the answer slightly wrong you can assume that your projection plane intersects in the centre of your collection of points, and, each degree of lat and lon are a constant number of metres. Then the problem is a simple planar calculation.
This is wrong, of course. I would actually recommend that you look into map projections, pick one that makes sense, and go for that. Remember that you can move the centre of the projection to the centre to your set of points which will reduce distortion.
I suspect that PROJ.4 might help you in terms of libraries. There also must be a good Java one but that is not my speciality.
Finally you can could assume that the earth is a sphere and do your calculations on the sphere. Or, if you really want to get it right you can pick a standard earth ellipsoid and do the calculations on that.
I have two Rectangles (call them A and B) on a game map and I've calculated the angle from the center of B to A. I have code that spawns a third (C) and "shoots" it from B to A. The problem is that in my game, two of these game elements should never overlap (they have collision code normally) so the "shooting" code is stopped - spawning C on top doesn't work logistically.
My solution (tell me if there's a better one) is to spawn the third rectangle next to the edge of the parent - but for the UI to function properly, it needs to always spawn off the edge of the parent that faces rectangle A.
I know the center coordinates for rectangle B, I know the angle (can be in radians or degrees) from B to A, how can I determine which side (left, top, right, bottom) the angle would point at?
Think of the square lying on the unit circle with its center at the origin. Then figure out if Java behaves like JavaScript which is backwards from standard trigenometry. (pi/2 is straight down in JS whereas it is straight up in standard trig). Rectangle objects also have boundary and intersection methods which may help.
The graphic a little down this page may help: http://en.wikipedia.org/wiki/Unit_circle
When I've written games with collision engines like this, and needed projectile launching behavior, there's been a couple different approaches I've taken.
First, I've maintained a reference to the entity that fired the projectile. Then in the collision detection method, I've compared against this reference.
Another option, which may be preferable, is to instead associate the entities to a "Faction". This could be modeled as an enum. Then the collision detection code could check to ensure the two entities are not in the same faction. You could also use a mapping to determine which factions collide with each other. For instance, you could have "Hostile", "Neutral", and "Player" factions and have the player faction entities not collide with Neutral, etc. It would depend on the "business rules" of your game.
If you do this, you can spawn the projectile anywhere you want.
Supposing that angle is the angle from center of B to center of A, given in radians in the interval -pi..pi, then the following should do what you want (remember that like #Jared suggested, positive angles are down rather than up):
double halfPi = Math.PI/2;
double theta = Math.atan2(B.height, B.width);
if (angle >= theta+halfPi || angle <= -theta-halfPi) {
// left side
} else if (angle >= theta) {
// bottom side
} else if (angle >= -theta) {
// right side
} else {
// top side
}
I'm trying to develop a Java3D method for rotating the universe in increments from the current viewing direction to the direction at the center of an object.
In other words, I want the 3D universe to rotate in, say, 100 short steps, so that an object that I click on appears to move gradually to the center of the screen.
I've reviewed the various answers to 3D rotation questions here on StackOverflow (as well as on the Web), but pretty much all of them are specific to rotating objects, not the world itself.
I've also tried to review my linear algebra, but that's not helping me to identify Java-specific functions that accomplish my requirements.
So far I've tried defining a set of incremental XYZ coordinates and dynamically using lookAt() in each pass through the loop. That almost works, but I don't see any way to preserve or obtain viewpoint values from one complete rotation pass to the next; each rotation pass starts out looking at the origin.
I've also tried defining a rotation matrix by obtaining the difference between the target and start transforms and dividing by the number of increments (and removing the scaling value), then adding that incremental rotation matrix to the current view direction at each pass through the loop. That works just fine for an increment value of 1. But splitting the rotation into two or more increments always generates the "BadTransformException: Non-congruent transform above ViewPlatform" error. (I've read the meager documentation of this exception in the Java3D API reference; it might as well have been written in Urdu for all I could make out from it. There seems to be no plain-English definition of 3D-context terms like "affine" or "shear" or "congruent" or "uniform" anywhere that Google can see.)
I then tried to cudgel my code into providing an AxisAngle4d, obtaining the angle (in radians), dividing that angle into my desired increments, and rotating by the incremental angle value. That rotated the world, all right, but nowhere near the object I picked, and not to any pattern I could see.
In desperation I tried using rotX and rotY (setting Z to the endpoint) on the extracted angle, and even blindly threw a couple of Math.cos() and Math.sin() wrappers in there. Still no joy.
My instincts are telling me that I've got the basics in place and that there's a relatively simple solution in Java3D. But clearly there's a comprehension wall I'm hitting. Rather than continue that, I thought I'd go ahead and see if anyone here can suggest a solution in Java3D. Code is preferred, but I'm willing to try to follow an explanation in linear algebra if that will get me to a code solution.
Below is the core of the method I'm using to schedule rotation increments using Java's Timer method. The part I need help with is just before the ActionListener. Presumably that's where the magic code would go that creates some kind of incremental rotation value I can apply (in the loop) to the current view direction in order to rotate the universe without getting "non-congruent" errors.
private void flyRotate(double endX, double endY, double endZ)
{
// Rotate universe by increments until target object is centered in view
//
// REQUIREMENTS
// 1. Rotate the universe by NUMROTS increments from an arbitrary (non-origin)
// 3D position and starting viewpoint to an ending viewpoint using the
// shortest path and preserving the currently defined "up" vector.
// 2. Use the Java Timer() method to schedule the visual update for each
// incremental rotation.
//
// GLOBALS
// rotLoop contains the integer loop counter for rotations (init'd to 0)
// viewTransform3D contains rotation/translation for current viewpoint
// t3d is a reusable Transform3D variable
// vtg contains the view platform transform group
// NUMROTS contains the number of incremental rotations to perform
//
// INPUTS
// endX, endY, endZ contain the 3D position of the target object
//
// NOTE: Java3D v1.5.1 or later is required for the Vector3D getX(),
// getY(), and getZ() methods to work.
final int delay = 20; // milliseconds between firings
final int pause = 10; // milliseconds before starting
// Get translation components of starting viewpoint vector
Vector3d viewVector = new Vector3d();
viewTransform3D.get(viewVector);
final double startX = viewVector.getX();
final double startY = viewVector.getY();
final double startZ = viewVector.getZ();
// Don't try to rotate to the location of the current viewpoint
if (startX != endX || startY != endY || startZ != endZ)
{
// Get a copy of the starting view transform
t3d = new Transform3D(viewTransform3D);
// Define the initial eye/camera position and the "up" vector
// Note: "up = +Y" is just the initial naive implementation
Point3d eyePoint = new Point3d(startX,startY,startZ);
Vector3d upVector = new Vector3d(0.0,1.0,0.0);
// Get target view transform
// (Presumably something like this is necessary to get a transform
// containing the ending rotation values.)
Transform3D tNew = new Transform3D();
Point3d viewPointTarg = new Point3d(endX,endY,endZ);
tNew.lookAt(eyePoint,viewPointTarg,upVector);
tNew.invert();
// Get a copy of the target view transform usable by the Listener
final Transform3D tRot = new Transform3D(tNew);
//
// (obtain either incremental rotation angle
// or congruent rotation transform here)
//
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if (++rotLoop <= NUMROTS)
{
// Apply incremental angle or rotation transform to the
// current view
t3d = magic(tRot);
// Communicate the rotation to the view platform transform group
vtg.setTransform(t3d);
}
else
{
timerRot.stop();
rotLoop = 0;
viewTransform3D = t3d;
}
}
};
// Set timer for rotation steps
timerRot = new javax.swing.Timer(delay,taskPerformer);
timerRot.setInitialDelay(pause);
timerRot.start();
}
}
As is often the case with these things, there may be a better way to do what I'm trying to accomplish here by stepping back and rethinking the problem. I'm open to constructive suggestions there as well.
Thanks very much for any assistance with this!
UPDATE
Let me try to define the goal a little more concretely.
I have a Java3D universe containing many Sphere objects. I can click on each object and dynamically obtain its predefined XYZ coordinates.
At any moment, I am looking at all currently visible objects with a "camera" at a particular XYZ position and a view direction, which are contained in a transform holding the rotation matrix and translation vector.
(Note: I can both rotate the universe and translate through it using the mouse independently of clicking on objects. So there will be times when the view transform containing the camera's current rotation matrix and translation vector is not pointing at any target object with known XYZ coordinates.)
Given the camera transform and the object's XYZ coordinates, I want to rotate the universe around my current camera position until the selected object is centered in the screen. And I want to do this as a sequence of discrete incremental rotations, each of which is rendered so that the visible universe appears to "spin" in the viewing window until the selected object is centered. (I'm following this up with a translation to the object; that part at least is working!)
Example: Suppose the camera is at the origin, "up" is 1.0 along the Y-axis, and the selected object is centered ten units directly to my left. Assuming I had a 180-degree field of view, I could click on the half of the sphere that is visible all the way to the left of the screen and halfway between the top and bottom of the screen.
When I give the word, every visible object in the universe should appear to move in a sequence of evenly-spaced steps (let's say 50) from my left to my right until the selected object is exactly centered in the screen.
In coding terms, I need to work out the Java3D code by which I can rotate the universe around an imaginary line that runs through my camera position (currently at 0,0,0) and that is perfectly aligned with the Y-axis of the universe's coordinate system. (I.e., the axis of rotation sweeps through a plane where Z is always equal to the Z component of the camera's position.)
The complicating requirements are:
The camera can be translated somewhere in 3D space other than the origin.
Objects can be anywhere in 3D space with respect to the camera's current position and view, including being visible but off the screen (outside the view frustum) entirely.
Rotations should take the shortest path -- no spinning the universe more than 180 degrees at a time.
There should not be any "jump" or "twisting" of the visible universe as the first step in the rotation process; i.e., the current "up" vector (not the universe's absolute "up" vector) should be preserved.
So there's the question: given a transform holding the (virtual) camera's current translation and rotation information, and the XYZ coordinates in universe space of a target object, what Java3D code will rotate the universe around the camera in N equal steps until the object is centered in the screen?
Presumably this solution is in two parts: first, some 3D math (expressed in Java3D) to calculate the incremental rotation information given only the camera transform and object's XYZ coordinates; second, a loop that [applies the incremental rotation to the current viewing transform and updates the screen] until the loop counter equals the number of increments.
It's that 3D math part that's beating me. I'm not seeing and can't bash out a way to obtain some form of incremental rotation information from the current camera transform and target object position that I can then apply to the camera transform. At least, I haven't found any way that doesn't cause jumping or twisting or unequal incremental movement steps (or a "non-congruent transform above ViewPlatform" exception).
There must be a simple solution....
So if I understand correctly, your goal is to rotate the camera so it centers on the selected object, but that rotation should not be about an arbitrary vector, but instead should preserve the camera's "up" direction.
A solution that might work then:
First, calculate the rotation angle (let's call it A) about the "up" vector necessary so that the camera is facing the object you want.
Second, calculate the translation distance/direction (let's call it D) necessary along the "up" vector so that the object lines up as necessary with the camera. This will likely just be the difference in the Z/Y coordinate between the camera/object.
Find dA and dD by diving A/D by N, the number of increments you want to take to smooth the motion.
In a timer/time loop increment A/D by dA/dD respectively N times, taking them to the final values. Remember that you are rotating the camera about it's "up" vector and current location, not about the origin..
If you want an even smoother, more realistic looking rotation, consider using SLERP.
I'm working on an Android game and would like to implement a 2D grid to visualize the effects of gravity on the playing field. I'd like to distort the grid based on various objects on my playing field. The effect I'm looking for is similar to the following from the Processing library:
Except that my grid will be simpler- 2D, and viewed strictly from the top, as if looking down at the playfield.
Can someone point me to an algorithm for drawing such a grid?
The one idea that I came up with was to draw the lines as if they were "particles"- start at one end of the screen and draw the line in multiple segments, treating each segment as a particle, calculating the effect of gravity at each segment's location.
The application is intended to run on Android.
Thanks
I would draw each line as a separate segment, as you mentioned. If the grid is sparse, it might be fastest.
If you are viewing the grid from above, you would need to calculate x and y coordinate displacements. The easiest way would be to actually do displacement along the z axis and then fake perspective with x_result = x/z and y_result = y/z . You set z=1 and make sure to vary it only relatively slightly (+- 0.1 for instance).
Your z should be proportional to the sum of 1/(distance to the sphere)^2. This simulates how gravity works - it tapers off with square of the distance. Great news - square of the distance means to calculate delta_x^2 + delta_y^2 - so you save yourself that square root calculation == faster.