I'm making a coastline fractal on a window that is one by one wide, and I would like to make the very first one pictured below, however, I cannot figure out which x and y coordinates to use to make the angles form 90 degrees and still fit on the screen, I don't need any code, I just would like how to figure out which x and y coordinates to use. Thanks!
Points:
1st point: (0,0.5)
2nd point: (0.25,0.75)
3rd point: (0.75,0)
4th point: (1,0.5)
My work (although messy and illegible at times):
It looks like from the picture that the first and last point both have a y-value of 0.5. Since the viewing window is one, you divide it into 4 parts each of which is 0.25 in length. The triangles that are formed if you draw a horizontal line at y=0.5 are isosceles according to the image. Thus, you solve: sin(45)=x/0.5.
re "x and y coordinates are doubles in between 0 and 1",
Then you will need to translate from your model (the set of points that make up your fractal) and the view (the GUI display). The model will go from 0 to 1, the view from 0 to the graphical window's width. A simple linear transformation where you multiply the model by some scale factor will serve.
Seems like you're wanting to map an abstract coordinate system to your screen.
Let's say your endpoints (in arbitrary coordinates) are (0, 0) and (1, 0). Then your points for the leftmost figure, in this system, will be (0, 0), (1/4, sqrt(2)/4), (1/2, 0), (3/4, -sqrt(2)/4), and (1, 0).
The other diagrams are calculated by some method. It sounded like your question was focusing on fitting it to the screen, so I'll continue with that. The method for fitting it to the screen is the same.
From there, you have a screen coordinate system. Each point is transformed to the screen. Let's say you have a 1000 by 1000 screen, with screen coordinates (0, 0) in the upper left. If you want to take up the entire screen, then you'd do the following:
Flip the y coordinates (+y is down on your screen)
Determine the full range in x and y for your arbitrary coordinates (1 for x, sqrt(2)/2 for y)
Multiply x values by 1000, and y values by 2000 / sqrt(2) to expand to the screen.
Subtract 500 from y values to center the image in the y direction.
Related
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 programming a Minecraft Bukkit plugin and need a way to calculate an input number from 0 to 360 for displaying a custom compass. So if the player directly looks at the object (shouldn't handle viewing height or position height), this number would be 0 and if the player's back is looking on the object it would be 180.
I already successfully calculated both numbers I need:
The absolute looking angle of the player. Is 0 when the player looks in north direction and 180 in south direction.
The location angle between the player's position and the object's position. Using Math.atan2 to get the angle between [X, Z] of these locations.
Both values seems to be calculated correctly. But I can't find out what to do to get the number I described at first. Tried substraction, addition. Any ideas?
It should be the difference between them - if the player is looking north, and the object delta x, delta z gives a bearing of 45 degrees then the needle should be in front and to the right at 45 (=45-0), if the player is looking south and tho object x,z is 45 then the needle should be behind and to the left at 225 or -135 (=45-180).
Check that you've converted the result of Math.atan2 to degrees so you're subtracting values in the same units, and that the axes conventions are consistent. This says that +ve x-axis is east and +ve z-axis is south. A bearing of 0, North is given by atan2(0,1), which implies that you should be using Math.toDegrees(Math.atan2(deltaX, -deltaZ)) to get the bearing.
When doing these sort of things, it's much easier to write up half a dozen unit tests which cover the cases and play with the signs to see what the effects are.
I am programming a 2D, grid-based Pacman game. All the tiles are 8x8 in size. In-game, the map tiles are treated as 16x16, and the characters (Pacman and the ghosts) are treated as 32x32. In actuality, they are all pulled from a spritesheet of 8x8 tiles. I store positions as the center point of each character. Since the character tiles are bigger than the map tiles, the map is built in a way that requires the characters being able to "overlap" onto blocked tiles.
To deal with this set of problems, I created an invisible Rectangle and attached it to the character's position. Where the position is an (x,y) point, the Rectangle is a box surrounding that point. This rectangle is essentially 16x16 in-game, and is in the center of the character, which allows for the overlap necessary.
This works fine if you're working with 8px as the global movement speed, but I'd like to treat 8px as "100% speed" and have complete control over character speed with a double that is in the range [0,1). The positions are stored as double points, so on that level, this is fine. I read the positions back as integers, though, since I'm working with pixels.
So the question I ask is essentially "if this moves X amount of pixels to direction Y now, will my collision box be touching a blocked tile? But if you're moving 5px at a time, this eventually causes a very obvious issue. Say you're at x = 0, moving right. The tiles are 16x16 in-game, as stated before, and you have two of these open before the third, which is blocked. So you move, x = 5, x = 10, x = 15, x = 20, we just got to the 2nd tile, x = 25, x = 30, x = 35 now we're in the 3rd tile... but wait. We can't go there, because X = 35 collides. And unfortunately, we needed to turn and start moving down, but we can't, because now our Y-axis isn't aligned properly with the grid. Our X position needs to be 32, but can't.
My question for everyone here is, what are my options? What are some ideas or insights you have? I have a feeling I'm making it more difficult than I need to.
sounds like you have...
Why not give your "pac-man" sprite a velocity vector? The vector will describe not only the speed at which "pac-man" is traveling but in what direction, meaning you can see ahead.
"pac-man" should be calculating and ultimately making a decision based upon the following conversation..."hey, moving at this speed and in this direction..in so many seconds I'm going to hit a wall, when does that happen?". The seconds don't even have to be seconds...they could be "squares".
You would need a function which takes in the initial movement vector (direction and speed) which returns a coordinate of an X,Y point where "pac-man" must stop, where he cannot go further and must change direction (the center of a tile adjacent to a wall). Each time "pac-man" changes direction, run this calculation again...you do not need to keep checking if the next square is passable. If his direction hasn't changed and his speed is constant..you only need calculate once and let the coordinate system do the rest.
With this approach, square size and velocity is irrelevant...until "pac-man" hits or within his next movement exceeds the stopping point, continue to move along the vector.
I'm trying to write a in-app joystick axis calibration tool.
The joystick axis area should be a rectangle, but in the reality it's a non-linear closed curve and I want to increase the accuracy.
The calibration should work this way:
we have a measured value, and this way we get the correct value:
Correct value = [(measured value)/range] * wantedrange
where range is the difference between the maximum and minimum value measured for that axis.
But there is also an offset to move the center point to the right position, how to calculate it?
EDIT: I also made an image: green rectangle is the expected area, red shape is the "real" inaccurate measured area, finally blue is the wanted calibrated area that I shift to (0,0) so that I can use the ratio to convert coordinates to the bigger green rectangle.
EDIT2:
This image explains how calibration can be even more accurate, thanks to zapl answer:
If we find the blue rectangle center, we can divide the rectangle in 4 rectangles and calculate a ratio between that range and the green rectangle's range.
And the code should be something like this:
if(value<axiscenter) correctedvalue = ((value-axismin)/(axiscenter-axismin)) * wantedaxisrange;
else correctedvalue = wantedaxisrange + ((value-offset-axiscenter)/(axismax-axiscenter-axismin)) * wantedaxisrange;
You can get the position of the blue rectangle by instructing the user to move the joystick along the edges so that the values you see are the red curve. You should also instruct user to leave joystick in centered position since you usually need to know the center. Calcuated center is not always the real center position.
For each axis separate those values by the side of the center they are on and find those that are the closest to the center point. That would work with calculated center. Now you have the blue rectangle.
E.g. on X axis you see values ranging from 0-20 and 80-100, center is ~50 > blue rectangle is 20 - 80.
Assuming you want to calibrate it so that values are 0-100 (green) you calculate correction for the x axis as
calibratedX = (uncalibrated - 20) * 100 / 60
Values are shifted by 20 to the right (-20 to normalize them to 0-60) and their range is 60 (80 - 20) which you want to upscale to 0-100. After that clip values to 0-100 since they will be outside for every point on the red line that was outside the blue rectangle.
Result looks like
where pink are the values after transformation, and the pink area outside the green rectangle is cut away.
Regarding the center point: just run it through those calculations as well.
I am currently trying to show a series of images that slightly differ from each other in a 3D view, and which contain lots of transparent areas (for example, points that move in time inside a rectangle, and I would provide a 3D view with all their positions over time).
What I'm doing now is generate an image with the points drawn in it, create one Boxes of 40x40x1 per frame (or rectangular shape of 40x40), apply the image as a texture to the FRONT side of the box, and add the boxes to my scenes at positions (0, 0, z) where z is the frame number.
It works quite well, but of course their is discontinuities (of 1 "meter") between the images.
I would like to know if their is a way to create an "extrusion" object based on that image so as to fill the space between the planes. This would be equivalent of creating one 1x1x1 box for each point, placing them at (x, y, z) where x/y are the point's coordinate and z the frame number. The actual problem is that I have lots of points (several hundreds, if not thousands in some cases), and what was relatively easy to handle and render with an image would, I think, become quite heavy to render if I have to create thousands boxes.
Thanks in advance for your help,
Frederic.
You could use 3d textue with your data (40 x 40 x N) pixels, N=number of frames.
But you still has to draw something with this texture enabled.
I would do what you are doing currently - draw quads, but no only along Z axis, but along X and Y too.
Each of N quads along Z axis would have 40x40 size, each of 40 quads along X axis would be 40xN size, and each of 40 quads along Y axis would be Nx40 size.
So for 2x2x2 textue we will draw 2+2+2 = 6 quads, and it will look like regular cube, for 3x3x3 points in texture we will draw 3+3+3 quads, and it will look like 8 cubes stacked into one big cube (so instead of 8 cubes 6 quads each we just draw 9 quads, but the effect is the same).
For 40x40x1000 it would be 1080 quads (reasonable to draw in real time imho) instead of 40*40*1000*6 quads.
I only don't know, if the graphical effect would be exactly what you wanted to achieve.