Given a 2D array of size 20x20 whose values resemble a 2D shape, for example a square or rectangle:
public static int[][] rectangle= {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
I would like to find its circumference and area in an algorithm that does the following:
Finds the nearest (1) point starting from the center (point[10][10]).
Uses the nearest (1) point as a starting point to iterate over all the remaining 1s to count the circumference.
calculates the number of zeros enclosed by the circumference to calculate the area
Now below is where I am currently at; the "guess" method calculates the nearest (1) point and executes the "count" method which then calculates the circumference.
public static void guess() {
boolean found = false;
if(!found) {
int y = 10;
for(int x = 10; x <= 20; x++) {
if(rectangle[x][y]==1) {
rectangle[x][y] = 2;
found = true;
break;
}else if(rectangle[x][y++]==1) {
rectangle[x][y] = 2;
found = true;
break;
}
}
}
if(!found) {
int y = 10;
for(int x = 10; x >= 0; x--) {
if(rectangle[x][y]==1) {
rectangle[x][y] = 2;
found = true;
break;
}else if(rectangle[x][y--]==1) {
rectangle[x][y] = 2;
found = true;
break;
}
}
}
if(!found) {
int x = 10;
for(int y = 10; y <= 20; y++) {
if(rectangle[x][y]==1) {
rectangle[x][y] = 2;
found = true;
break;
}else if(rectangle[x][y++]==1) {
rectangle[x][y] = 2;
found = true;
break;
}
}
}
if(!found) {
int x = 10;
for(int y = 10; y >= 0; y--) {
if(rectangle[x][y]==1) {
rectangle[x][y] = 2;
found = true;
break;
}else if(rectangle[x][y--]==1) {
rectangle[x][y] = 2;
found = true;
break;
}
}
}
for(int i = 0; i < 20; i++) {
for(int j = 0; j < 20; j++) {
if(rectangle[i][j] == 2) {
Count(i, j);
break;
}
}
}
}
public static void Count(int x, int y) {
public int circumf;
int tx = x;
int ty = y;
for(int c = 40; c >=0; c--) {
if((c/2)-1<0 || x>=20 || x<0 || y>=20 || y<0) break;
if(rectangle[x][(int) (c/2)-1]==1 || rectangle[(int) (c/2)-1][y]==1
|| rectangle[x++][y]==1 || rectangle[x][y++]==1
|| rectangle[x--][(int) (c/2)-1]==1 || rectangle[(int) (c/2)-1][y--]==1 || rectangle[x--][y]==1 || rectangle[x][y--]==1) {
circumf++;
}
}
x = tx;
y = ty;
for(int c = 0; c <=40; c++) {
if((c/2)>=20 || x>=20 || x<0 || y>=20 || y<0) break;
if(rectangle[x][(int) (c/2)]==1 || rectangle[(int) (c/2)][y]==1
|| rectangle[x++][y]==1 || rectangle[x][y++]==1
|| rectangle[x--][(int) (c/2)]==1 || rectangle[(int) (c/2)]
[y--]==1 || rectangle[x--][y]==1 || rectangle[x][y--]==1) {
circumf++;
}
}
System.out.print(circumf);
Now, the guess method calculates the nearest point correctly, however the count method doesn't correctly counts the circumference which is close to 70 in the above example.
As for the area calculating algorithm, I still didn't quite figure it out.
The above code isn't the most brilliant or organized thing I know, but any help would be really appreciated!
Suppose you find the nearest one at index [i][j]
. You need to check the nearest values in a cross pattern since your object is a rectangle.
For example you are in the middle one in the left edge of the rectangle:
0 1 0
0 1 0
0 1 0
You check were the 1's "continue" finding thus the edge direction. There are 2 possible outcomes either
[x-1][y]=[x][y]=[x+1][y] or [x][y-1]=[x][y]=[x][y+1]==1
So,you found that the edge is vertical. Continue iterating through this verical line until the condition [x][y-1]==1
is false
. Then do the same thing for the horizontal line.
Now for the 0's count you could store the index i,j of all the corners while you are doing the above check.If you know their positions and the size of the array is fixed you can calculate the 0's like:
0's area = [(DL_corner_index - 1) - (UL_corner_index + 1)] x [(UR_corner_index - 1) - (UL_corner_index + 1)]
int rectangle[10][10] ={
{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0}
};
//calculating area of zeros with known corner coordinates
//you have stored the coordinates in variables like this
int UL_X=1,UR_X=8;
int UL_Y=1,DL_Y=8;
int area = ((UR_X-1) - UL_X)*((DL_Y-1)-UL_Y);
cout<<area; //36
}