Here is my problem statement:
There is a matrix of octagons, for example, 4 octagons in a row and 3 such rows. So 4 columns and 3 rows of octagons. But they are not arranged in a perfect rectangle form.
Case1:
The first Octagon, O(0,0) has coordinates(0,0), while the one at its right and the one at bottom are at a bit offset. So O(0,1) has coordinates (15,50) and O(1,0) has coordinates (30,15). This information is enough to define the whole array of octagons. Now next requirement is to find how much is the net visible area of these octagons. In the first example, as the coordinates are far away, there would be no overlapping and total visible area is simply...
Total_Visible_Area = Area_of_Single_Octagon * No_Of_Rows * No_Of_Columns
But when the coordinates are bit complex, for example, Case 2:
Here, the the distance between the adjacent octagons is less than their width and hence they are overlapping. Coordinates also are negative (which does not matter much actually, just something to note). Now to determine visible area for this I wrote the following function.
//Inputs of the function:
//S = Side of the octagon/2, 5*Accuracy_Factor for both of the case
//G = Total Width of the octagon/2, 5*2.41*Accuracy_Factor for both of the case
//NSX = X distance of the octagon O(1,0), 8.09*Accuracy_Factor in Case 2
//NSY = Y distance of the octagon O(1,0), -20.98*Accuracy_Factor in Case 2
//EWX = X distance of the octagon O(0,1), 17.37*Accuracy_Factor in Case 2
//EWY = Y distance of the octagon O(0,1), 12*Accuracy_Factor in Case 2
//NSCount = Total no of rows, 4 in this example
//EWCount = Total no of columns, 3 in this example
//The following function initializes a big 2D array. Each pixel of the octagon is one
//element of the array. Program calculates coordinates of all octagons. Picking the
//octagons one by one, it forms an octagon around that coordinate in the
//2D array by allotting 1 to the array. At the end I find a total number
//of 1s ant that's my total visible area.
double OverlapArea(double S, double G, double NSX, double NSY, double EWX, double EWY, int NSCount, int EWCount)
{
int count = 0, i, j, x, y, ArrayColSize, ArrayRowSize, TotalArea;
double XMax = 0, XMin = 0, YMax = 0, YMin = 0, DishX[3], DishY[3], A, B, Ai, Bi;
std::vector<std::vector<int>> Area;
//Next few line, until the next comment, are written to find the
//size of the 2D array that will be required.
DishX[0] = EWX * (EWCount - 1);
DishX[1] = NSX * (NSCount - 1);
DishX[2] = EWX * (EWCount - 1) + NSX * (NSCount - 1);
DishY[0] = EWY * (EWCount - 1);
DishY[1] = NSY * (NSCount - 1);
DishY[2] = EWY * (EWCount - 1) + NSY * (NSCount - 1);
for (i = 0; i < 3; i++)
{
if (DishX[i] < XMin)
XMin = DishX[i];
if (DishX[i] > XMax)
XMax = DishX[i];
if (DishY[i] < YMin)
YMin = DishY[i];
if (DishY[i] > YMax)
YMax = DishY[i];
}
A = Ai = G - XMin;
B = Bi = G - YMin;
ArrayRowSize = (int)ceil(XMax - XMin + 2 * G);
ArrayColSize = (int)ceil(YMax - YMin + 2 * G);
Area.resize(ArrayRowSize+5, std::vector<int>(ArrayColSize+5, 0));
//Array is resized in the above line, not the loop that forms the octagons
for (i = 0; i < NSCount; i++)
{
for (j = 0; j < EWCount; j++)
{
for (x = A - G; x < A + G; x++)
{
for (y = B - G; y < B + G; y++)
{
if ((x - y >= A - B - S - G) && (y <= B + G) && (x + y <= A + B + S + G) && (x <= A + G) && (x - y <= A + G - B + S) && (y >= B - G) && (x + y >= A + B - S - G) && (x >= A - G))
{
Area[x][y] = 1;
}
}
}
A = Ai + EWX * (j+1);
B = Bi + EWY * (j+1);
count++;
}
A = Ai + NSX;
B = Bi + NSY;
Ai = A;
Bi = B;
}
TotalArea = 0;
for (i = 0; i < ArrayRowSize; i++)
{
for (j = 0; j < ArrayColSize; j++)
{
TotalArea = TotalArea + Area[i][j];
std::cout << Area[i][j]<<',';
}
std::cout <<std::endl;
}
return (double)TotalArea;
}
Now the problem with this method:
- The Accuracy factor that I set in the main function determines how accurate this method is. Higher the accuracy is, more the time to calculate. It's as simple as increasing resolution.
- I can only use the shapes that I can define with equations (rectangle, circle, triangle octagon etc...) If it's an irregular shape, I'll have a tough time defining which pixel to count and which to not.
I'd like to know other methods I can calculate visible area. One thing I can think of is inputting the shape as an image, overlapping it, and then calculate the pixels at the end. But not sure if there is a more simple way.
Edit: The main function is going to calculate 8000+ cases, out of which approx 3000 cases will require to go through this function. The Accuracy Factor needs to be an odd multiple of 7 (7,21,35,49...Found this via experimenting. 7 has more accuracy than 20.). With Accuracy factor = 21, the program took around 1 hour for its first 2000 calculations, after which I terminated it cause I had the idea that it's working good. But this time is unacceptable.
