I am trying to make a grid out of angular spirals. The spiral itself is composed of single lines within a for loop. When I duplicate and shift (translate) the origin of the spiral along one axis (x OR y) it works. But shifting along both (x AND y), in order to make it a grid, it does not work out without decomposing the spiral.
I would really appreciate if anyone could help me with my coding puzzle. By the way I'm very open-minded for any tips and help improving my code writing skills. There surely is a lot of redundancy and long-winded expressions in there...
This is my code so far:
function drawSpiral() {
let count = 8;
let stepX = 8;
let stepY = 8;
let tileSize = 100;
let pixelX = tileSize;
let pixelY = tileSize;
for (let j = 0; j < 5; j++) {
let x1 = 0;
let y1 = 0;
let x2 = 0;
let y2 = 0;
let x3 = 0;
let y3 = 0;
let x4 = 0;
let y4 = 0;
for (let i = 0; i < count; i++) {
x1 += stepX;
x2 -= stepX;
x3 -= stepX;
x4 += stepX;
y1 += stepY;
y2 += stepY;
y3 -= stepY;
y4 -= stepY;
push();
translate(pixelX, pixelY);
line(x1, y1, x2 - stepX, y2)
line(x2 - stepX, y2, x3 - stepX, y3 - stepY);
line(x3 - stepX, y3 - stepY, x4 + stepX, y4 - stepY);
line(x4 + stepX, y4 - stepY, x1 + stepX, y1 + stepY);
pop();
}
pixelX += tileSize * 2; //shifting either along x-axis
}
}
What a beauty, huh? Yeah you're guessing right – I'm new to the coding business ;)
If you're trying to make a grid of spirals it looks like you just need to use a pair of for loops where you currently have for (let j = 0; j < 5; j++) {. Pretty much any time you want to create a grid you're going to want a pair of nested for loops.
function setup() {
createCanvas(800, 800);
}
function draw() {
background(100);
drawSpiral();
}
function drawSpiral() {
let count = 8;
let stepX = 8;
let stepY = 8;
let tileSize = 100;
let pixelX = tileSize;
let pixelY = tileSize;
// Make a 5x5 grid of spirals
for (let row = 0; row < 5; row++) {
for (let col = 0; col < 5; col++) {
let x1 = 0;
let y1 = 0;
let x2 = 0;
let y2 = 0;
let x3 = 0;
let y3 = 0;
let x4 = 0;
let y4 = 0;
for (let i = 0; i < count; i++) {
x1 += stepX;
x2 -= stepX;
x3 -= stepX;
x4 += stepX;
y1 += stepY;
y2 += stepY;
y3 -= stepY;
y4 -= stepY;
push();
translate(pixelX, pixelY);
line(x1, y1, x2 - stepX, y2)
line(x2 - stepX, y2, x3 - stepX, y3 - stepY);
line(x3 - stepX, y3 - stepY, x4 + stepX, y4 - stepY);
line(x4 + stepX, y4 - stepY, x1 + stepX, y1 + stepY);
pop();
}
// Sift right for each col
pixelX += tileSize * 2;
}
// Shift down for each row
pixelY += tileSize * 2;
// And reset the horizontal position at the end of each row
pixelX = tileSize;
}
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.3.1/lib/p5.js"></script>
Related
Hi I am confused as to what is wrong with my code related to the "edges" filter portion of the problem.
I am able to apply a filter that detects edges. For some reason I fail the check50. I am only able to apply the filter to middle pixels. Any guidance would be much appreciated. I am wondering if I am approaching this problem the incorrect way.
With this code I am just ignoring the calculations for the "black pixels" or the pixels outside of the range of height/width.
Here is my code:
void edges(int height, int width, RGBTRIPLE image[height][width])
{
//create temporary array
RGBTRIPLE temp[height][width];
for (int i = 0; i < height; i ++)
{
for (int j = 0; j < width; j++)
{
temp[i][j] = image[i][j];
}
}
//initialize sobel arrays
int gxarray[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
int gyarray[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};
//loop through each ith pixel in jth column
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j ++)
{
float gx_red = 0;
float gx_blue = 0;
float gx_green = 0;
float gy_red = 0;
float gy_blue = 0;
float gy_green = 0;
//use the temporary array grid to calculate each gx value
//check if it is a corner or side pixel - and treat that pixel as black pixel
for (int k = -1; k < 2; k ++)
{
for (int l = -1; l < 2; l ++)
{
//calculate the gx and gy for each color by multiply each of
//check if they are corner or sidepixels
if (i + k < 0 || i + k >= height)
{
continue;
}
if (j + l < 0 || j + l >= width)
{
continue;
}
//otherwise calculate each color value
gx_red += temp[i + k][j + l].rgbtRed * gxarray[k + 1][l + 1];
gx_blue += temp[i + k][j + l].rgbtBlue * gxarray[k + 1][l + 1];
gx_green += temp[i + k][j + l].rgbtGreen * gxarray[k + 1][l + 1];
gy_red += temp[i + k][j + l].rgbtRed * gyarray[k + 1][l + 1];
gy_blue += temp[i + k][j + l].rgbtBlue * gyarray[k + 1][l + 1];
gy_green += temp[i + k][j + l].rgbtGreen * gyarray[k + 1][l + 1];
}
}
//times each number by itself then, add them, then square root them
int red = 0 + round(sqrt(gx_red * gx_red + gy_red * gy_red));
int blue = 0 + round(sqrt(gx_blue * gx_blue + gy_blue * gy_blue));
int green = 0 + round(sqrt(gx_green * gx_green + gy_green * gy_green));
image[i][j].rgbtRed = red;
image[i][j].rgbtBlue = blue;
image[i][j].rgbtGreen = green;
//cap it by 255
if (image[i][j].rgbtRed > 255)
{
image[i][j].rgbtRed = 255;
}
if (image[i][j].rgbtBlue > 255)
{
image[i][j].rgbtBlue = 255;
}
if (image[i][j].rgbtGreen > 255)
{
image[i][j].rgbtGreen = 255;
}
}
}
return;
}
```[enter image description here][1]
[1]: https://i.stack.imgur.com/3bExI.png
Hey guys i have been trying to figure out the problem with my code of the pset4 filter (more) about edge detection. My code compiles but the result image looks strange, with a lot of bright/white pixels and very little color pixels mostly at the boundaries of the image. I think i am close to the right result but i just can't figure it out by myself. Could someone plz check it out? appreciate any inputs!
I have treated the edges or corner pixels of the original image by creating copied image with extra lines and columns, which contain only black pixels (rgb values = 0). And i have also used copied image to store the temporary calculation results from the loop.
void edges(int height, int width, RGBTRIPLE image[height][width])
{
// sobel filters
int Gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
int Gy[3][3] = {{-1, -2, -1}, {0, 0 ,0}, {1, 2, 1}};
// creates copied image to story the original image and extra lines/columes
// of black pixels to loop through
RGBTRIPLE temp[height + 2][width + 2];
for (int i = 0; i < height + 2; i++)
{
for (int j = 0; j < width + 2; j++)
{
if (i == 0 || j == 0 || i == height + 1 || j == width + 1)
{
temp[i][j].rgbtRed = 0;
temp[i][j].rgbtGreen = 0;
temp[i][j].rgbtBlue = 0;
}
else
{
temp[i][j] = image[i - 1][j - 1];
}
}
}
// second copied image with extra black pixels to store the result
RGBTRIPLE temp2[height + 2][width + 2];
for (int i = 0; i < height + 2; i++)
{
for (int j = 0; j < width + 2; j++)
{
temp2[i][j] = temp[i][j];
}
}
//calculation based on the copied image
for (int i = 1; i < height + 1; i++)
{
// varibles to stroy Gx Gy for each color channels
float blueGx = 0.0, redGx = 0.0, greenGx = 0.0;
float blueGy = 0.0, redGy = 0.0, greenGy = 0.0;
for (int j = 1; j < width + 1; j++)
{
for (int k = -1; k < 2; k++)
{
for (int h = -1; h < 2; h++)
{
//calculate the Gx for each R G B channel by using temp
blueGx += temp[i + k][j + h].rgbtBlue * Gx[k + 1][h + 1];
redGx += temp[i + k][j + h].rgbtRed * Gx[k + 1][h + 1];
greenGx += temp[i + k][j + h].rgbtGreen * Gx[k + 1][h + 1];
//calculate the Gy for each R G B channel by using temp
blueGy += temp[i + k][j + h].rgbtBlue * Gy[k + 1][h + 1];
redGy += temp[i + k][j + h].rgbtRed * Gy[k + 1][h + 1];
greenGy += temp[i + k][j + h].rgbtGreen * Gy[k + 1][h + 1];
}
}
//store result for each pixels (i, j) in temp2
temp2[i][j].rgbtRed = maxCheck(round(sqrt(redGx * redGx + redGy * redGy)));
temp2[i][j].rgbtBlue = maxCheck(round(sqrt(blueGx * blueGx + blueGy * blueGy)));
temp2[i][j].rgbtGreen = maxCheck(round(sqrt(greenGx * greenGx + greenGy * greenGy)));
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j] = temp2[i + 1][j + 1];
}
}
}
// cap rgb value to 255
int maxCheck(int a)
{
if (a > 255)
{
a = 255;
}
return a;
}
by using check50 i got four errors:
:( edges correctly filters middle pixel
expected "210 150 60\n", not "255 250 255\n"
:( edges correctly filters pixel on edge
expected "213 228 255\n", not "255 255 255\n"
:( edges correctly filters 3x3 image
expected "76 117 255\n21...", not "76 117 255\n25..."
:( edges correctly filters 4x4 image
expected "76 117 255\n21...", not "76 117 255\n25..."
seeing from the results a lot of pixels have been calculated up to 255. That explains all the white pixels in the result image but i don't understand why. Something wrong with the math? i think i did pay attention to the number range of rgb values and the difference between int and float number.
check50
just found out the problem: the reset of blueGx, redGx etc. is at the wrong position, which doesn't reset them properly at the beginning of each loop for a new pixel.
I want to know the length of a Path.
For example, if I have a straight line I can just compute the length with its start x,y and end x,y values. But it gets quickly very tricky if I use QuadCurves or CubicCurves.
Is there any way to get the length or an approximation of the length of a Path?
For example the following path:
Path path = new Path();
MoveTo moveTo = new MoveTo(start.getX(), start.getY());
double controlPointX = 50;
CubicCurveTo cubicCurveTo = new CubicCurveTo(start.getX() + controlPointX, start.getY(),
start.getX() + controlPointX, end.getY(), end.getX(), end.getY());
path.getElements().addAll(moveTo, cubicCurveTo);
I needed this recently as well. I couldn't find any solutions online, but it occurred to me PathTransition must be calculating it. It does, see PathTransition.recomputeSegment, where totalLength is calculated.
Unfortunately, it uses many internal APIs in Node and the PathElement to convert the Path to a java.awt.geom.Path2D. I extracted these methods out and replaced other usages of com.sun classes with java.awt ones, then pulled the parts relevant to calculating length out of PathTransition.recomputeSegments.
The resulting code is below. It is in Kotlin not Java, but it should be easy to convert it back to Java. I have not yet tested it extensively but it seems to be working on the fairly complex paths I have tested it against. I've compared my results to the length calculated by PathTransition and they are very close, I believe the discrepancies are due to my code using Path2D.Double where as Path2D.Float is used by PathElement.impl_addTo.
fun Transform.toAffineTransform(): AffineTransform {
if(!isType2D) throw UnsupportedOperationException("Conversion of 3D transforms is unsupported")
return AffineTransform(mxx, myx, mxy, myy, tx, ty)
}
val Path.totalLength: Double
get() {
var length = 0.0
val coords = DoubleArray(6)
var pt = 0 // Previous segment type
var px = 0.0 // Previous x-coordinate
var py = 0.0 // Previous y-coordinate
var mx = 0.0 // Last move to x-coordinate
var my = 0.0 // Last move to y-coordinate
val pit = toPath2D().getPathIterator(localToParentTransform.toAffineTransform(), 1.0)
while(!pit.isDone) {
val type = pit.currentSegment(coords)
val x = coords[0]
val y = coords[1]
when(type) {
PathIterator.SEG_MOVETO -> {
mx = x
my = y
}
PathIterator.SEG_LINETO -> {
val dx = x - px
val dy = y - py
val l = sqrt(dx * dx + dy * dy)
if(l >= 1 || pt == PathIterator.SEG_MOVETO) length += l
}
PathIterator.SEG_CLOSE -> {
val dx = x - mx
val dy = y - my
val l = sqrt(dx * dx + dy * dy)
if(l >= 1 || pt == PathIterator.SEG_MOVETO) length += l
}
}
pt = type
px = x
py = y
pit.next()
}
return length
}
fun Path.toPath2D(): Path2D {
val path: Path2D = Path2D.Double(if(fillRule == FillRule.EVEN_ODD) Path2D.WIND_EVEN_ODD else Path2D.WIND_NON_ZERO)
for(e in elements) {
when(e) {
is Arc2D -> append(e as ArcTo, path) // Why isn't this smart casted?
is ClosePath -> path.closePath()
is CubicCurveTo -> append(e, path)
is HLineTo -> append(e, path)
is LineTo -> append(e, path)
is MoveTo -> append(e, path)
is QuadCurveTo -> append(e, path)
is VLineTo -> append(e, path)
else -> throw UnsupportedOperationException("Path contains unknown PathElement type: " + e::class.qualifiedName)
}
}
return path
}
private fun append(arcTo: ArcTo, path: Path2D) {
val x0 = path.currentPoint.x
val y0 = path.currentPoint.y
val localX = arcTo.x
val localY = arcTo.y
val localSweepFlag = arcTo.isSweepFlag
val localLargeArcFlag = arcTo.isLargeArcFlag
// Determine target "to" position
val xto = if(arcTo.isAbsolute) localX else localX + x0
val yto = if(arcTo.isAbsolute) localY else localY + y0
// Compute the half distance between the current and the final point
val dx2 = (x0 - xto) / 2.0
val dy2 = (y0 - yto) / 2.0
// Convert angle from degrees to radians
val xAxisRotationR = Math.toRadians(arcTo.xAxisRotation)
val cosAngle = Math.cos(xAxisRotationR)
val sinAngle = Math.sin(xAxisRotationR)
//
// Step 1 : Compute (x1, y1)
//
val x1 = cosAngle * dx2 + sinAngle * dy2
val y1 = -sinAngle * dx2 + cosAngle * dy2
// Ensure radii are large enough
var rx = abs(arcTo.radiusX)
var ry = abs(arcTo.radiusY)
var Prx = rx * rx
var Pry = ry * ry
val Px1 = x1 * x1
val Py1 = y1 * y1
// check that radii are large enough
val radiiCheck = Px1 / Prx + Py1 / Pry
if (radiiCheck > 1.0) {
rx *= sqrt(radiiCheck)
ry *= sqrt(radiiCheck)
if(rx == rx && ry == ry) {/* not NANs */ }
else {
path.lineTo(xto, yto)
return
}
Prx = rx * rx
Pry = ry * ry
}
//
// Step 2 : Compute (cx1, cy1)
//
var sign = if (localLargeArcFlag == localSweepFlag) -1.0 else 1.0
var sq = (Prx * Pry - Prx * Py1 - Pry * Px1) / (Prx * Py1 + Pry * Px1)
sq = if (sq < 0.0) 0.0 else sq
val coef = sign * Math.sqrt(sq)
val cx1 = coef * (rx * y1 / ry)
val cy1 = coef * -(ry * x1 / rx)
//
// Step 3 : Compute (cx, cy) from (cx1, cy1)
//
val sx2 = (x0 + xto) / 2.0
val sy2 = (y0 + yto) / 2.0
val cx = sx2 + (cosAngle * cx1 - sinAngle * cy1)
val cy = sy2 + (sinAngle * cx1 + cosAngle * cy1)
//
// Step 4 : Compute the angleStart (angle1) and the angleExtent (dangle)
//
val ux = (x1 - cx1) / rx
val uy = (y1 - cy1) / ry
val vx = (-x1 - cx1) / rx
val vy = (-y1 - cy1) / ry
// Compute the angle start
var n = sqrt(ux * ux + uy * uy)
var p = ux // (1 * ux) + (0 * uy)
sign = if (uy < 0.0) -1.0 else 1.0
var angleStart = (sign * Math.acos(p / n)).toDegrees()
// Compute the angle extent
n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy))
p = ux * vx + uy * vy
sign = if (ux * vy - uy * vx < 0.0) -1.0 else 1.0
var angleExtent = Math.toDegrees(sign * Math.acos(p / n))
if(!localSweepFlag && angleExtent > 0) angleExtent -= 360.0
else if(localSweepFlag && angleExtent < 0) angleExtent += 360.0
angleExtent %= 360
angleStart %= 360
//
// We can now build the resulting Arc2D
//
val arcX = cx - rx
val arcY = cy - ry
val arcW = rx * 2.0
val arcH = ry * 2.0
val arcStart = -angleStart
val arcExtent = -angleExtent
val arc = Arc2D.Double(OPEN).apply { setArc(arcX, arcY, arcW, arcH, arcStart, arcExtent, OPEN) }
val xform: AffineTransform? = when(xAxisRotationR) {
0.0 -> null
else -> AffineTransform().apply { setToRotation(xAxisRotationR, cx, cy) }
}
val pi = arc.getPathIterator(xform)
// RT-8926, append(true) converts the initial moveTo into a
// lineTo which can generate huge miter joins if the segment
// is small enough. So, we manually skip it here instead.
pi.next()
path.append(pi, true)
}
private fun append(cubicCurveTo: CubicCurveTo, path: Path2D) {
if(cubicCurveTo.isAbsolute) {
path.curveTo(cubicCurveTo.controlX1, cubicCurveTo.controlY1,
cubicCurveTo.controlX2, cubicCurveTo.controlY2,
cubicCurveTo.x, cubicCurveTo.y)
}
else {
val dx = path.currentPoint.x
val dy = path.currentPoint.y
path.curveTo(cubicCurveTo.controlX1 + dx, cubicCurveTo.controlY1 + dy,
cubicCurveTo.controlX2 + dx, cubicCurveTo.controlY2 + dy,
cubicCurveTo.x + dx, cubicCurveTo.y + dy)
}
}
private fun append(hLineTo: HLineTo, path: Path2D) {
if(hLineTo.isAbsolute) path.lineTo(hLineTo.x, path.currentPoint.y)
else path.lineTo(path.currentPoint.x + hLineTo.x, path.currentPoint.y)
}
private fun append(lineTo: LineTo, path: Path2D) {
if(lineTo.isAbsolute) path.lineTo(lineTo.x, lineTo.y)
else path.lineTo(path.currentPoint.x + lineTo.x, path.currentPoint.y + lineTo.y)
}
private fun append(moveTo: MoveTo, path: Path2D) {
if(moveTo.isAbsolute) path.moveTo(moveTo.x, moveTo.y)
else path.moveTo((path.currentPoint.x + moveTo.x), path.currentPoint.y + moveTo.y)
}
private fun append(quadCurveTo: QuadCurveTo, path: Path2D) {
if(quadCurveTo.isAbsolute) {
path.quadTo(quadCurveTo.controlX, quadCurveTo.controlY,
quadCurveTo.x, quadCurveTo.y)
}
else {
val dx = path.currentPoint.x
val dy = path.currentPoint.y
path.quadTo(quadCurveTo.controlX + dx, quadCurveTo.controlY + dy,
quadCurveTo.x + dx, quadCurveTo.y + dy)
}
}
private fun append(vLineTo: VLineTo, path: Path2D) {
if(vLineTo.isAbsolute) path.lineTo(path.currentPoint.x, vLineTo.y)
else path.lineTo(path.currentPoint.x, path.currentPoint.y + vLineTo.y)
}
I am applying two equations of rotation to rotate gray scale images easily. It's not rotating, however.
The two equations are:
x' = x *cos (theta) - y *sin (theta)
and
y' = x *sin (theta) + y *cos (theta)
I have visited a number of Q&A's on this site but the explanations are unclear.
IMG imgRotate(IMG output, float deg)
{
IMG lalo;
lalo.degree = deg;
float radian = ((2 *pi*output.degree) / 360);
float cosine = cos(radian);
float sine = sin(radian);
int x1 = (output.height * sine);
int y1 = (output.height * cosine);
int x2 = (output.width * cosine + output.height* sine);
int y2 = (output.height* cosine -output.width * sine);
int x3 = (output.width * cosine);
int y3 =(-output.width * sine);
int minx = min(0, min(x1, min(x2, x3)));
int miny = min(0, min(y1, min(y2, y3)));
int maxx = max(0, max(x1, max(x2, x3)));
int maxy = max(0, max(y1, max(y2, y3)));
int w = maxx - minx;
int h = maxy - miny;
int x, y,nx,ny;
lalo.pixel = (unsigned char*)calloc(lalo.height*lalo.width, sizeof (unsigned char));
for (y = 0; y < h; y++)
{
for (x = 0; x <w; x++)
{
nx = ceilf(x*cos(radian) - y*sin(radian));
ny = ceilf(x*sin(radian) + y*cos(radian));
lalo.pixel[w*ny + nx] = output.pixel[w*ny + nx];
}
}
return lalo;
}
I have added the following code but it is giving incomplete image
IMG imgRotate(IMG output,float deg, int height, int width)
{
IMG lalo;
lalo.degree = deg;
lalo.width = width;
lalo.height = height;
lalo.pixel=(unsigned char*)calloc (lalo.height*lalo.width, sizeof (unsigned char));
float radian = ((2 *pi*lalo.degree) / 360);
int x, y, x1, y1;
for (y = 0; y < lalo.height; y++)
{
for (x = 0; x <lalo.width; x++)
{
x1 = ceilf(x*cos(radian)-y*sin(radian));
y1 = ceilf(x*sin(radian) + y*cos(radian));
lalo.pixel[lalo.width*y1+x1] = output.pixel[output.width*x1+y1];
}
}
return lalo;
}
this is the we do with css it may help not sure
.image-class {
/* Rotate div */
-ms-transform: rotate(45deg); /* IE 9 */
-webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
transform: rotate(45deg);
}
<img class="image-class" src="https://media-mediatemple.netdna-ssl.com/wp-content/uploads/images/behavioral-css/transform_rotate.png"/>
I can draw my map according to the formula on Drawing Isometric game worlds . But how can i find the x-y of one tile according to it's position on map layer div?
For being clear, my tile's left style is 1036px and top style is 865px. According to those css properties how can find the tile's x and y position according to map?
Tile width is 200 and height is 100.
Many Thanks.
My javascript code is like that:
this.drawTiles = function(min_x, max_x, min_y, max_y) {
if (min_x < 0) min_x = 0;
if (min_y < 0) min_y = 0;
if (max_x < 0) max_x = thisObj.MAXSIZE;
if (max_y < 0) max_y = thisObj.MAXSIZE;
if (max_x > this.mapSize - 1) max_x = this.mapSize - 1;
if (max_y > this.mapSize - 1) max_y = this.mapSize - 1;
if (min_x < this.mapSize - 1) min_x = max_x - thisObj.MAXSIZE;
if (min_y < this.mapSize - 1) min_y = max_y - thisObj.MAXSIZE;
var appendLayer = thisObj.maplayer;
this.capMapDataObj.getTiles(min_x, max_x, min_y, max_y, function(JSONResp) {
var tiles = JSON.parse(JSONResp);
for (var x=min_x; x<max_x+1; x++) {
for (var y=min_y; y<max_y+1; y++) {
var tile = tiles[x][y];
var xpos = (y * thisObj.tile_width / 2) + (x * thisObj.tile_width / 2);
var ypos = (x * thisObj.tile_height / 2) - (y * thisObj.tile_height / 2);
var zin1 = 100 + parseInt(x) + parseInt(y);
var elem = '<div style="position:absolute;top:'+ypos+'px;left:'+xpos+'px;z-index:'+zin1+';width:200px;height:200px;background-image:url(images/'+tile[4]+');background-position:bottom;background-repeat:no-repeat;bottom:0px;text-align:center;" id="'+x+'_'+y+'"><div style="padding-top:140px;">'+x+' - '+y+'</div></div>\n';
if (document.getElementById(x+'_'+y) == undefined)
$(elem).appendTo(appendLayer);
}
}
});
}
So xpos and ypos variables are the css positions of each tile layer. When i click the Map Layer, I wanted to calculate the tile's isometric x-y coordinates.
I've solved the problem.
tileX = (yPos / tile_height) + (xPos / tile_width);
tileY = (xPos / tile_width) - (yPos / tile_height);