Skip to content

Instantly share code, notes, and snippets.

@edwardtoday
Last active August 29, 2015 13:57
Show Gist options
  • Save edwardtoday/9457248 to your computer and use it in GitHub Desktop.
Save edwardtoday/9457248 to your computer and use it in GitHub Desktop.
Find largest rectangle for a new window in a canvas with some existing windows.
#include <stdio.h>
#include <stdlib.h>
/**
* @brief Find largest rectangle for a new window in a canvas with some existing windows.
* @param width Canvas width in pixel
* @param height Canvas height in pixel
* @param objects Existing objects, in the form {{x_topleft,y_topleft,x_bottomright_y_bottomright},...}
* @param num_objects Number of objects in previous parameter
* @param output Array to store result as {x_topleft,y_topleft,x_bottomright_y_bottomright}
*/
void find_largest_rect(int width, int height, int (*objects)[4],
int num_objects, int* output) {
// create canvas array
unsigned char* canvas = (unsigned char*)malloc(width * height * sizeof(
unsigned char));
int* up = (int*)malloc(width * sizeof(int));
int* up_last = (int*)malloc(width * sizeof(int));
int* left = (int*)malloc(width * sizeof(int));
int* left_last = (int*)malloc(width * sizeof(int));
int* right = (int*)malloc(width * sizeof(int));
int* right_last = (int*)malloc(width * sizeof(int));
int ans = 0, lo = 0, ro = 0;
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
int i = 0, j = 0, k = 0;
// set whole canvas to 1
for (i = 0; i < height; i++)
for (j = 0; j < width; j++) {
canvas[i * (width) + j] = 1;
}
// initialize temp vars
for (j = 0; j < width; j++) {
up[j] = 0;
up_last[j] = 0;
left[j] = 0;
left_last[j] = 0;
right[j] = 0;
right_last[j] = 0;
}
// set occupied points to 0
for (i = 0; i < num_objects; i++) {
x1 = objects[i][0];
y1 = objects[i][1];
x2 = objects[i][2];
y2 = objects[i][3];
// boundary check
x1 = x1 < 0 ? 0 : (x1 > width ? width : x1);
y1 = y1 < 0 ? 0 : (y1 > height ? height : y1);
x2 = x2 < 0 ? 0 : (x2 > width ? width : x2);
y2 = y2 < 0 ? 0 : (y2 > height ? height : y2);
for (j = y1; j <= y2; j++) {
for (k = x1; k <= x2; k++) {
canvas[j * (width) + k] = 0;
}
}
}
x1 = 0, y1 = 0, x2 = 0, y2 = 0;
for (i = 0; i < height; i++) {
lo = -1;
ro = width;
// store last temp vars
for (j = 0; j < width; j++) {
up_last[j] = up[j];
left_last[j] = left[j];
right_last[j] = right[j];
}
// initialize up[] and left[] for current i
for (j = 0; j < width; j++) {
if (canvas[i * width + j] == 0) {
left[j] = up[j] = 0;
lo = j;
}
else {
up[j] = (i == 0) ? 1 : up_last[j] + 1;
left[j] = (i == 0) ? lo + 1 : ((left_last[j] > lo + 1) ?
left_last[j] : lo + 1);
}
}
for (j = width - 1; j >= 0; j--) {
if (canvas[i * width + j] == 0) {
right[j] = width;
ro = j;
}
else {
right[j] = (i == 0) ? ro - 1 : ((right_last[j] < ro - 1) ?
right_last[j] : ro - 1);
}
if (up[j] * (right[j] - left[j] + 1) > ans) {
ans = up[j] * (right[j] - left[j] + 1);
x1 = left[j];
y1 = i - up[j] + 1;
x2 = j;
y2 = i;
}
}
}
output[0] = x1;
output[1] = y1;
output[2] = x2;
output[3] = y2;
printf("Max rectangle area = %d\n", ans);
// print canvas
// for (i = 0; i < height; i++) {
// printf("%d\t", i);
// for (j = 0; j < width; j++) {
// printf("%d", *(canvas + i * (width) + j));
// }
// printf("\n");
// }
free(canvas);
free(up);
free(up_last);
free(left);
free(left_last);
free(right);
free(right_last);
}
int main(void) {
//canvas properties
int width = 30;
int height = 20;
// objects in canvas
int num_objects = 3;
int objects[3][4] = {{0, 0, 9, 9}, {20, 0, 29, 19}, {5, 14, 14, 18}};
// var to store result coordinates of topleft and bottomright vertices (x1,y1,x2,y2)
int output[4] = {0, 0, 0, 0};
find_largest_rect(width, height, objects, num_objects, output);
printf("(%d,%d)->(%d,%d)\n", output[0], output[1], output[2], output[3]);
return 0;
}
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
find_largest_rect.c