My maths isn't that good so I'm having a bit of trouble in one of my applications that I'm trying to do where I want a rectangle to represent a vehicle and I want that vehicle/rectangle to "drive" around in a circle. Imagine a roundabout with only 1 vehicle in it, just circling around forever.
If I can get some help how to do that then I'll be able to build on the example and most importantly learn.
If someone could write up a simple example for me I'd be grateful. No background no images, just a rectangle "driving" around in a circle. I'm using java and Swing.
Sorry, I am not sure if could understand clear you exactly need. If you need to draw rectangle which is moving around inside of circle, you can use sin/cos functions.
Something like that:
double r = 50.0; // radius (it might radius of your circle, but consider dimensions of rectangle to make sure you are drawing inside of circle, e.g. circleRadius - rectangeDimesion / 2.0)
for (int f = 0; f < 360; f++) {
double x = Math.sin(Math.toRadians((double)f)) * r;
double y = Math.cos(Math.toRadians((double)f)) * r;
// draw rectangle on [x, y] coordinates
}
If you know the radius of the round about, all the you would need would be a trigonometric function and the angle which the vehicle makes to the round about. You could take a look at this simple introduction which should get you started in the right direction.
On another hand, another approach would be to use a Transformation Matrix where you start with a matrix containing two points (your X and Y co-ordinates) and you transform them to become the new co-ordinates.
You can then rotate the rectangle to mimic a vehicle turning.
If you have a limited background in Mathematics, the first option might be easier for you to grasp.
This is more an extended comment than an answer.
I would divide the problem up into several easier problems, and work on each of them separately:
Draw your rectangle with a specified center location and long axis orientation.
Determine the center point and long axis orientation for an object orbiting around the origin. Note that to get make the long axis a tangent it needs to be perpendicular to the radius through the center.
Translate the whole system so that it orbits the desired point, rather than the origin.
Related
So I'm making a TD game where I can place a gatling gun, and depending on which sector of a surrounding circle the mouse is in, the sprite and bullet path will change.
My difficulty is with creating an algorithm which will tell me which sector my mouse is in.
My circle has 16 sectors, and a radius of 300. Each arc has a length of 117.81.
Extending from (300,300), I have an exact list of all the coordinates of the lines, so I am able to currently draw the sector like this:
Circle
I'm using a mouse listener to detect the coordinates of my mouse whenever my mouse moves, so I have a "currentPoint" to check within which sector it's in.
Based on this information, can anyone think of an easy way to simply return an integer of which sector the mouse is currently inside? Preferably somewhat efficiently.
These are the two ways I'm thinking about how it would look:
Two_Ideas
And I did look at this StackOverflow which seemed like a similar problem: Efficiently find points inside a circle sector
And I implemented it with Java, but it doesn't seem to translate without having Vectors and I'm a bit too confused about the math to make it work.
Been trying to figure this out for a while, I would love any help with an implementation of any kind, (don't mind adding Trig calculations), along with any help understanding the problem.
Thank you!!
To get sector, you need to get angle relative to point center.
Pseudocode (I am not sure how math functions and rounding look in Java):
double angle = math.atan2(mouse.y-center.y, mouse.x-center.x);
angle = angle - math.pi / 16.0;
while (angle < 0) {
angle = angle + 2*math.pi;
}
sector = math.floor(angle * 8.0 / math.pi);
I made correction by half-sector becouse your first sector is centered around OX axis.
I've created a simple planetary simulation where a planet orbits a star.
The code for the orbit is this:
a = a + vel * delta;
planetX = Math.cos(a) * orbitRadius + parentStar.getX();
planetY = Math.sin(a) * orbitRadius + parentStar.getY();
Now that works just fine, but my problem is that the orbit is not from the center of the planet around the center of the star.
This is what happens
As you can see, the first red dot on the small circle is the Position of the planet wich orbits around the second small red dot, this is because the circle is drawn from (0,0), so both the planets (0,0) circles around the (0,0) of the star.
I need the the center of the planet to circle the stars center, not their origin point.
Is there a good fix for this?
Your calculation of the orbit is fine. The only problem seems to be that you treat "position" differently when calculating orbits and when drawing the planets: When you draw them, you treat x and y as one of the corner points, but when you calculate the oribit, you treat them as the centre of the body. The simplest way would be to change the visualisation, not the calculation.
Since you did not post the code you use to draw the shapes, I can only guess, but I assume it looks somewhat like this (obviously Pseudocode):
for (Planet p : starsAndPlanets) {
drawCircle(p.x, p.y, p.radius * 2, p.radius * 2);
}
Change this to something like this:
for (Planet p : starsAndPlanets) {
drawCircle(p.x - p.radius, p.y - p.radius, p.radius * 2, p.radius * 2);
}
This way, x and y are the position of the centre of the planet, and with p.x - p.radius and p.y - p.radius you get the corner point. Of course, you could in a similar way change all your orbital mechanic formulas to calculate the centre from the corner point, but IMHO it is much simpler and more natural to treat x and y as the centre.
For now the most suitable way I can think of is getting the star's world coordnates and passing them every frame to the child's coordinates. As you do so, the child would have the same coordinates everyframe.
The next part is translating it and rotating it around the Star - the way you can achieve that is by setting the planet's position to be transposed by the Star's position with a sin(x)*cos(x).
Let me show you an example:
planet[0] = star[0] + sin(angle)*scale
planet[1] = star[1] + cos(angle)*scale
Where the angle would change incrementally and the scale will just shift the child object further from its parent, keeping it a constant (or modifying it if you wish) thus increasing the radius from its 'new' center.
I know some people may mention matrices or other types of transformations, but for this situation I think the above solution would be most relevant and cleanest in my opinionp
The way it works is you take the parent's 'WORLD coordinates' and set them to be the child's. By modifying the Scale value you increase the distance of the object from the center (so they won't overlap) and you multiply this with the sin and cos of the angle you specified to make it rotate.
P.S. Keep in mind that if you're dealing an FPS-dependant engine to render, the more FPS the faster the simulation will be, and vice-versa, because if you render at 1000 fps, this means you execute your code 1000 times, compared to 100 for example. Therefore, you will increment the angle 1000 times or 100 respectively. If you have this issue, try setting a constant framerate if you can - it's the simplest workaround for lightweight simulations.
Edit: I forgot to mention that the concept works for all objects in your case. You just have to work our the relationships and use the function for eqch object seperately where each object has a position and angle of orbit (if it orbits around a different object).
I am trying to write a program in java from scratch that renders a sphere with ray casting technique and phong illumination, but I am a bit lost.
I understand the concept behind the phong equation coefficients, but I don't understand how to get to the vector values, and what is the relation of all this with ray casting
so let's say I want to renders the sphere in the middle of my screen, and I have it's position and radius, so (cx,cy,r). Where exactly do I start now? how exactly do I get to the vector values? my idea is as follows (pseudocode)
int cx = window width/2
int cy = window height/2
int r = 30;
for(i = 0 -> window height) {
for(j = 0 -> window width) {
if( (j-cx)^2 + (i-cy)^2 < r^2) {
//point inside
Color c = phong(arguments..)
draw pixel j,i with color c
}
}
}
but I have no idea if this is correct or not, and if it is, how do I get the vector values, for starters, the Normal?
could you point me in the right way? I have tried googling a lot with no success, thank you in advance
The vectors for calculating the normal usually come from a tessellation (approximation) of the real geometrical object. So you break the sphere up into, say, triangles. Then each triangle (p1,p2,p3) has its own normal vector ((p2-p1)×(p3-p1).
The phong shading method is an interpolation which then (ideally) blurs over the lines that give away the fact that you're drawing triangles instead of a true sphere. It's doesn't help with corners around the sides, though. :(
For the tessellation, one way is to approximate the sphere with Bezier surface patches which can then be subdivided to a suitably small sizes and simplified to triangles. My question over here explores doing this work to draw a teapot (mostly surfaces of revolution, not unlike spheres).
UPDATE: I think I figured it out. The scaleMultiplier also applied to the translate that I was trying to do. I had a suspicion this was the case but couldn't figure out exactly how it got affected.
Anyone familiar with a spinoff of Java called Processing? I'm trying to do something simple, scale a shape and place it in the center of the sketch. This is my code in a nutshell:
pushMatrix();
float scaleX, scaleY, scaleMultiplier, resetX, resetY, transX, transY;
scaleX = 500 / (float)clickState.bounds.getWidth();
scaleY = 500 / (float)clickState.bounds.getHeight();
scaleMultiplier = min(scaleX,scaleY);
resetX = -(float)clickState.bounds.getX();
resetY = -(float)clickState.bounds.getY();
transX = resetX + ((800 - ((float)clickState.bounds.getWidth() * scaleMultiplier))/2);
transY = resetY + ((550 - ((float)clickState.bounds.getHeight() * scaleMultiplier))/2);
scale(scaleMultiplier);
shape(clickState.pshape, transX, transY);
popMatrix();
What I'm trying to do is scale a state on a US Map. clickState is the state that the user clicked on. clickState.bounds is a Rectangle that surrounds the shape of the state. getX() and getY() return the x and y coords of the upper left hand corner of said box. I want to scale the state so that it's no bigger than 500x500 pixels. After that, I want to translate it so that it's in the middle of the sketch, which is 800x550.
Here's where I run into trouble: When I do
shape(clickState.pshape, resetX, resetY);
It draws the state in the upper left hand corner of the sketch. That's exactly what it should do. Then from there I want to add the number of pixels that it would take to center the shape, which is what transX and transY are for. However, when I use transX and transY, the shape gets drawn almost completely off the canvas, depending on where the state is located (even if its only being moved 50 pixels to the right from 0,0). It doesn't make any sense to me whatsoever. I've tried all sorts of combinations of translate(), and even skipping scale() altogether and using a width and height in shape(). It's like Processing is trying to frustrate me on purpose. Any help is appreciated.
I'm not familiar with Processing, but matrix operations are not commutative—the order matters. Typically, operations are applied in an apparent last-specified-first-applied order, as shown in this example.
Vince, I think I was trying to do something very similar last week. Sounds like you figured it out, but check out the answers on this board:
http://forum.processing.org/topic/how-do-i-move-svg-child-shapes#25080000000689051
I am doing a mashup using Google Maps under Grails where users can create geofences by selecting a point on the map and a radius. This get stored on my database and the application receives constantly a set of coordinates from a GPS device.
I would like to compare the received coordinates with the area stored in the circles. If the point is inside (or outside) the circle the program will fire an action. However, I would like to know how I can find out if the coordinates are located inside/outside the circle. There is a Javascript library which allows doing this but I need to do this on the server.
Is there a Java (or even Groovy) library for this?
How would you implement it?
if distance from point to center of circle is <= radius of circle then it is inside the circle.
if the area is made of more than one circle than compare to all the circles... it won't take that long.
java.awt.geom.Point2D.Double is perfect for this.
Well, if it doesn't need to be "perfect", you don't need to worry about plotting circles or anything like that. You can just take the two locations (the location you want to test, and the center of the circle) and use Pythagorus to find the distance. If that distance is less than the radius of the circle, it's inside.
There is a caveat to take into consideration, however: the reason this wouldn't be perfect is that that for your points, you're probably going to get a latitude and longitude...and the Earth is a sphere. So near the poles of the Earth this will kind of fall apart. But it may well be good enough for what you're doing.
Sadly, most of the responses here won't work for you conveniently, because GPS coordinates are in units of degrees. You will need something to convert from two points in Degrees of latitude and longitude to a great circle distance, which simple Pythagorean theorem falls short of.
If you're using Google maps API, you can probably do everything you need using GLatLng. As other posters have noted, You can determine the distance between two points is less than the radius of the specified circle. Specifically GLatLng.distance(other:GLatLng) returns the meters distance between too GPS locations.
To actually display the circles requires a bit more finesse. You will need to create a GPolygon to draw the circumference of the circle. You can find a number of free JavaScript functions that can do this for you.
Victor and Beska have the correct answer. That is, if the distance between the point and the center is less than the radius, then it's in the circle.
For the great circle distance between two points, you can use GeoTools' GeodeticCalculator. In particular you set the point and radius using setStartingGeographicPoint and setDestinationGeographicPoint followed by calling getOrthodromicDistance which will return the distance.
You want to find the vector that is the distance between the selected coordinate and the center of the circle, then compute the square distance between the selected coordinate and the center of the circle by squaring the components of the vector and adding them together; if that scalar (the squared distance) is less than the square of the radius, the point is within the circle.
This method avoids having to take a square root, and is just as accurate as normal distance comparison.
One possibility is to calculate the distance from the centerpoint and compare it to the radius.
Depending on you application you may be have to take into account that the world is a sphere and not 2Dimensional. To calcualte a distance on earth you can use this formula.
Since you are using Google Maps and for geographical distances spherical geometry holds rather than euclidean geometry. However if it is relativley smaller distance like a parking lot etc. then you can use euclidean distance formula (http://en.wikipedia.org/wiki/Distance) to find out whether the point is inside or outside the circle.
I presume you know the coordinates of the circle's center C(xc, yc) and its radius, R. Then for a given point P(x1, y1) find the euclidean distance, D as
square-root((x1-xc)^2 + (y1-yc)^2)). If D > R, the point lies outside the circle. If D < R, the point lies inside the circle. If D = R, the point lies on the circumference of the circle.
In case you are doing your measurements over larger distances then you should rather look for Geodesics (please check this http://en.wikipedia.org/wiki/Great-circle_distance).
I hope it helps.
cheers