Last active
August 29, 2015 13:57
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TEMPLATE = app | |
CONFIG += console | |
CONFIG -= app_bundle | |
CONFIG -= qt | |
SOURCES += \ | |
find_largest_rect.c | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Run it at http://ideone.com/RqcJkM
References:
http://blog.csdn.net/roney_win/article/details/8744582
http://architecture.riaos.com/?p=3005971
http://hi.baidu.com/517145/item/1499a0f42dad5518d99e720c
http://old.blog.edu.cn/user4/253559/archives/2008/2041835.shtml
http://www.wohenniu.com/thread-1120-1-1.html
http://blog.sina.com.cn/s/blog_64018c250100sc4d.html
http://blog.csdn.net/hopeztm/article/details/7870387
http://blog.csdn.net/wahaha1_/article/details/8887017
http://www.verydemo.com/demo_c180_i54126.html