I'm in the process of building a isometric framework so far I've got the physical tile mapping algorithm down.
The thing is I don't want per tile collision, as in looping through all the tiles to check if my mouse is selecting a specific tile.
What I tried to accomplish is get cell index from the mouse using this.
int col = (int)(((double)mouse_x / (double)tileWidth) - ((double)mouse_y / (double)tileHeight) - 0.5);
int row = (int)(((double)mouse_y / (double)tileHeight) + ((double)mouse_x / (double)tileWidth) - 0.5);
But using this method my 0,15 is the 0,0 according to the mouse and the 0,0 is the 0,15.
So my question is how can I swap that around by editing the mouse code perhaps using offset?Even so I wouldn't know how, so my question is how.
I just went with the simple way out, instead of editing the initials equation.
I modified the outcome by:
int col = (int)(((double)mouse_x / (double)tileWidth) - ((double)mouse_y / (double)tileHeight) - 0.5);
int row = (int)(((double)mouse_y / (double)tileHeight) + ((double)mouse_x / (double)tileWidth) - 0.5);
row = mapHeight - row - 1;
This flips the outcome, and thus fixes my problem in a non-artistic equational manner.
From isometric coordinates to screen coordinates:
screenX = (isoX - isoY + isoMapMaxY) * (tileWidth / 2);
screenY = (isoX + isoY) * (tileHeight / 2);
From screen coordinates to isometric coordinates:
isoX = ( ((screenY + scrollY) / tileHeight) + ((screenX + scrollX) - (isoMapMaxY * tileWidth/2)) / tileWidth )
isoY = ( ((screenY + scrollY) / tileHeight) - ((screenX + scrollX) - (isoMapMaxY * tileWidth/2)) / tileWidth )
isoX = (screenY / 32) + (screenX - 320) / 64
isoY = (screenY / 32) - (screenX - 320) / 64
Related
Right now im Creating an 3D game for android/OpenGL the sence is to fly through such 3D Rings made with index Buffer Objects as shown in the pictures.
My Problem: Actually my twisted Loop is generating the Coordinates like it should but if i translate it got squezzed,
because this is causing in this case the Y Coordinate not to match to the z Coordinate.
I tried around a few days finding a way to compensate this issue but succesless,
anyone of you could say me a way creating a translateble 3D Ring in OpenGL/android with or even without my basics that would Help me very well.
for (int y = 0; y < 32; y++) {
for (int x = 0; x < 32; x++) {
final float xPosR = 0.5f * (float) Math.cos((x) * move) ; //move = 2*Pi/31 : In this part the x coordinates are getting builded (after rotating they are actually the z coordinates)
final float yPosR = translationY + (float) Math.sin((y) * move) //translation = 1[enter image description here][1]/0 otherwise you could do it as translation with the modelmatrix
+ 0.5f * (float) Math.cos((x) * move) * (float) Math.cos((y) * move) ; //In this part the Y Coordinates are getting builded
final float zPosR = - (1f * (float) Math.cos((y) * move)) +
0.5f * (float) Math.cos((x) * move) * (float) Math.sin((y) * move); //In this part the z Coordinates are getting builded(after rotating they are actually the z coordinates)
//in the onDrawFrame Method it gets rotate 90 degree around the y-axis and translated -5 in the z-axis
heightMapVertexDataR[offsetR++] = xPosR;
heightMapVertexDataR[offsetR++] = yPosR;
heightMapVertexDataR[offsetR++] = zPosR;
Translation = 1
Translation = 0
I have been writing a image editing application for fun and all is well but i have ran into a problem with the zoom feature. The image editor plane is 512 x 512 pixels large but the image i want to edit is only 16 x 16. I want to know how to project my mouse coordinates to the smaller image to edit it pixel by pixel.
i have devised this algorithm to to such.
/**
*
* #param pointx The x position of the point thats being bound
* #param pointy The y position of the point thats being bound
* #param oldsizeX The old grid size x of which the point is currently in. ( eg ==> 512*512)
* #param oldsizeY The old grid size y of which the point is currently in. ( eg 512* ==> 512)
* #param newsizeX The new grid size x for the new grid size of the point. ( eg ==> 16*16)
* #param newsizeY The new grid size y for the new grid size of the point. ( eg 16* ==> 16)
* #param normalOffsetX The offset x, if any, the grid has in the normal plane ( eg ==> 32*32 # (512*512))
* #param normalOffsetY The offset y, if any, the grid has in the normal plane ( eg 32* ==> 32 # (512*512)
* #return A Vector2 containing the bound points in the new plane.
*/
public static Vector2 bindPoint(int pointx, int pointy, int oldsizeX, int oldsizeY, int newsizeX, int newsizeY,int normalOffsetX,int normalOffsetY) {
Vector2 vec = new Vector2();
int tileSizeX = oldsizeX / newsizeX;
int tileSizeY = oldsizeY / newsizeY;
int offsetX = normalOffsetX, offsetY = normalOffsetY;
vec.x = (int) (pointx / 2) / (oldsizeX / tileSizeX) - (offsetX / tileSizeX);
vec.y = (int) (pointy / 2) / (oldsizeY / tileSizeY) - (offsetY / tileSizeY);
if(pointx >= normalOffsetX && pointx <= normalOffsetX + oldsizeX && pointy >= normalOffsetY && pointy <= normalOffsetY + oldsizeY) {
return vec;
}else {
return new Vector2(-1,-1);
}
}
This works as long as the smaller resolution is 16x16 and i have found that if i change the 2 after the pointX and pointY division to 0.5 and an image of 32x32 works. What i want to know is if there is a better way to do so, so that i can use any size image at any zoom level?
You should not use integers to represent the position. Use double instead when you do the calculations. In the end, when you have calculated everything and need a pixel value, round the double to an integer. Otherwise you will have lose precision all over the place (which explains the problems you see).
You get different results depending on how you use your brackets. For example, from a math point of view the below Systems out's should give you the same result, but they don't:
int i = 700;
int j = 70;
int k = 30;
System.out.println((i / 2) / (j / k)); --> 175
System.out.println(i / 2 / j * k); --> 150
I figured it out on my own lol, sorry, its late and i spaced and forgot how to proportion.
Here is the answer for anyone else who needs it!
/**
*
* #param pointx The x position of the point thats being bound
* #param pointy The y position of the point thats being bound
* #param oldsizeX The old grid size x of which the point is currently in. ( eg ==> 512*512)
* #param oldsizeY The old grid size y of which the point is currently in. ( eg 512* ==> 512)
* #param newsizeX The new grid size x for the new grid size of the point. ( eg ==> 16*16)
* #param newsizeY The new grid size y for the new grid size of the point. ( eg 16* ==> 16)
* #param normalOffsetX The offset x, if any, the grid has in the normal plane ( eg ==> 32*32 # (512*512))
* #param normalOffsetY The offset y, if any, the grid has in the normal plane ( eg 32* ==> 32 # (512*512)
* #return A Vector2 containing the bound points in the new plane.
*/
public static Vector2 bindPoint(int pointx, int pointy, int oldsizeX, int oldsizeY, int newsizeX, int newsizeY,int normalOffsetX,int normalOffsetY) {
Vector2 vec = new Vector2();
int tileSizeX = oldsizeX / newsizeX;
int tileSizeY = oldsizeY / newsizeY;
int offsetX = normalOffsetX, offsetY = normalOffsetY;
vec.x = (int) Math.floor(pointx * ((float) newsizeX) / (float) oldsizeX) - (offsetX / tileSizeX);
vec.y = (int) Math.floor(pointy * ((float) newsizeY) / (float) oldsizeY) - (offsetY / tileSizeY);
return vec;
}
I have a circle of let's say 10 of radius with the center x=0 y=0. And I have a number n (e.g. 3). I want to get a point from that circle. Here is an explanation with an image:
So if n=0, the method would return 0;-6
And if n=1, the method would return 3;-5
etc.
But the method would receive parameters like the unit between each n etc.
The equation of a circle is
x = x0 + r * cos(a)
y = y0 + r * sin(a)
with (x0, y0) the center of the circle and a in 0...2Pi
so if you want y given x you will have :
sin(a) = (y - y0)/r
so
a = arcsin((y - y0)/r) if ((y - y0)/r is in -PI/2..PI/2)
a = -arcsin((y - y0)/r) if ((y - y0)/r is in -PI..-PI/2 or PI/2..PI)
a is undefine elsewhere
therefore
y = y0 + r * sin(arcsin((y - y0)/r)) if ((y - y0)/r is in -PI/2..PI/2))
y = y0 + r * sin(-arcsin((y - y0)/r)) if ((y - y0)/r is in -PI..-PI/2 or PI/2..PI))
y is undefine elsewhere
Use the roots of unity, it will give you the exponential form of a complex on the circle. You can then use the Euler formula to get the real coordinates of your point. Of course, since your circle is not unitary, you must take into account its radius.
I need to draw random shapes on a grid such as lines squares etc. This part I'm able to do. My problem is the start and end point of the lines I'm drawing falls anywhere in a grid cell. I would like them to be only at intersection points. One cell in the grid is a 10x10 pixel grid. Do i have to write an algorithm to assign the pixel to its nearest intersection point on the grid or is there a easier way. I'm using a buffered image to draw the grid. Please Help. this is what i have so far
for (int i = 0; i < 61; i++) {
g2d.drawLine((imgDim.width + 2) / 40 * i, 0,
(imgDim.width + 2) / 40 * i, imgDim.height - 1);
g2d.drawLine(0, (imgDim.height + 2) / 60 * i,
imgDim.width - 1, (imgDim.height + 2) / 60 * i);
}
Thank you
How are you coming up with the random points? Making an adjustment there might be the easiest way. That is, just drop a 0 in the process you are using to come up with the points in the first place. Then when you are ready to draw it, add a 0 back.
Seriously? In order to make a random point (pixelX, pixelY) snap to the closest point of a grid.
int gridSize = 10;
int x = (pixelX + gridSize / 2) / gridSize * gridSize;
int y = (pixelY + gridSize / 2) / gridSize * gridSize;
Alright, so I got a bit of movement code and I'm thinking I'm going to need to manually input when to go up/down a slope. All I got to work with is the slope's normal, and vector, and My current and previous position, and my yaw.
Is there a better way to rotate whether I go up or down the slope based on my yaw?
Vector3f move = new Vector3f(0,0,0);
move.x = (float)-Math.cos(Math.toRadians(yaw));
move.z = (float)-Math.sin(Math.toRadians(yaw));
System.out.println("slopeNormal.z: " + slopeNormal.z + "move.z: " + move.z);
move.normalise();
float vx = (float) (Math.sqrt(Math.pow(move.y, 2) + Math.pow(move.z, 2)) * move.x);
float vy = (float) (Math.sqrt(Math.pow(move.x, 2) + Math.pow(move.z, 2)) * move.y);
float vz = - vx * slopeNormal.x - vy * slopeNormal.y;
move.scale(movementSpeed * delta);
if(vz < 0)
move.y -= slopeVec.y * 1.5f;
if(vz > 0)
move.y += slopeVec.y * 1.5f;
Vector3f.add(pos, move, pos);
Edit: updated code.
First off, the following is incorrect:
move.x = (float)-Math.toDegrees(Math.cos(Math.toRadians(yaw)));
move.z = (float)-Math.toDegrees(Math.sin(Math.toRadians(yaw)));
Math.toDegrees converts an angle in radians to one in degrees, but the results of Math.cos and Math.sin are not angles.
Assume zero yaw is in the positive x-direction... and define vx, vy, vz = rate of motion along 3 axes, s = speed, and slope normal = nx, ny, nz where nx^2 + ny^2 + nz^2 = 1. So nx = ny = 0, nz = 1 would be flat.
First, I define x', y' = axes relative to the flat ground (motion is constrained to ground). Then (the following is not valid Java, but I'm enclosing it in code format anyway):
vx' = cos(yaw) * s
vy' = sin(yaw) * s
Then I need to rotate from x', y' coordinates to real-world coordinates. That is done using the slope normal:
vx = sqrt(vy^2 + vz^2) vx'
vy = sqrt(vx^2 + vz^2) vy'
vz = - vx' nx - vy' ny
A check on this transformation: vx^2 + vy^2 + vz^2 must equal vx'^2 + vy'^2 = s^2. I think this works out.
So to answer your question: up or down? vz > 0 is up, vz < 0 is down.