Created
January 31, 2025 05:35
-
-
Save lardratboy/441f98a8f9aa484149c53eca90e97c87 to your computer and use it in GitHub Desktop.
quick and dirty python->javascript version of repack.py
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
class Rect { | |
constructor(left, top, right, bottom) { | |
this.left = left; | |
this.top = top; | |
this.right = right; | |
this.bottom = bottom; | |
} | |
width() { return this.right - this.left; } | |
height() { return this.bottom - this.top; } | |
} | |
class Page { | |
constructor(width, height) { | |
this.width = width; | |
this.height = height; | |
this.free_rects = [new Rect(0, 0, width, height)]; | |
this.occupied_rects = []; | |
} | |
static *external_clipped_rects(a, b) { | |
let top = a.top, bottom = a.bottom; | |
if (a.top < b.top) { | |
top = b.top; | |
yield new Rect(a.left, a.top, a.right, b.top); | |
} | |
if (a.bottom > b.bottom) { | |
bottom = b.bottom; | |
yield new Rect(a.left, b.bottom, a.right, a.bottom); | |
} | |
if (a.left < b.left) { | |
yield new Rect(a.left, top, b.left, bottom); | |
} | |
if (a.right > b.right) { | |
yield new Rect(b.right, top, a.right, b.bottom); | |
} | |
} | |
insert(width, height) { | |
for (let i = 0; i < this.free_rects.length; ++i) { | |
const free_rect = this.free_rects[i]; | |
if (free_rect.width() < width || free_rect.height() < height) continue; | |
const rect = new Rect(free_rect.left, free_rect.top, free_rect.left + width, free_rect.top + height); | |
this.occupied_rects.push(rect); | |
this.free_rects.splice(i, 1); // Remove free_rect at index i | |
let free_count = this.free_rects.length; | |
for (const clipped_rect of Page.external_clipped_rects(free_rect, rect)) { | |
this.free_rects.push(clipped_rect); | |
} | |
if (free_count !== this.free_rects.length) { | |
this.free_rects.sort((x, y) => (x.height() - y.height())); | |
} | |
return rect; | |
} | |
return null; | |
} | |
calculate_efficency() { | |
const total_area = this.width * this.height; | |
let used_area = 0; | |
for (const rect of this.occupied_rects) { | |
used_area += rect.width() * rect.height(); | |
} | |
return used_area / total_area; | |
} | |
} | |
class Packer { | |
constructor(width, height) { | |
this.pages = [new Page(width, height)]; | |
this.page_width = width; | |
this.page_height = height; | |
} | |
insert(width, height) { | |
for (const page of this.pages) { | |
const rect = page.insert(width, height); | |
if (rect) return { page: page, rect: rect }; | |
} | |
const new_page = new Page(this.page_width, this.page_height); | |
this.pages.push(new_page); | |
const rect = new_page.insert(width, height); | |
return { page: new_page, rect: rect }; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment