380 lines
38 KiB
Plaintext
380 lines
38 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from matplotlib.patches import Rectangle\n",
|
|
"from matplotlib.collections import PatchCollection\n",
|
|
"from random import choice\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"# Hilfsfunktionen\n",
|
|
"\n",
|
|
"def norm_ratio (x):\n",
|
|
" return np.max([x, 1/x])\n",
|
|
"\n",
|
|
"class Rect(Rectangle):\n",
|
|
" def __str__(self):\n",
|
|
" return f\"A={round(self.w * self.h,3)}, x={round(self.xy[0],3)}, y={round(self.xy[1],3)}, width={round(self.w,3)}, height={round(self.h,3)}, ratio={round(norm_ratio(self._width/self._height),3)}\"\n",
|
|
"\n",
|
|
" xy = property(Rectangle.get_xy, Rectangle.set_xy)\n",
|
|
" h = property(Rectangle.get_height, Rectangle.set_height)\n",
|
|
" w = property(Rectangle.get_width, Rectangle.set_width)\n",
|
|
"\n",
|
|
"def difference (rect1, rect2):\n",
|
|
" remains = []\n",
|
|
" if (rect2.xy[0] > rect1.xy[0]):\n",
|
|
" remains.append(Rect(rect1.xy, rect2.xy[0] - rect1.xy[0], rect1.h))\n",
|
|
" if (rect2.xy[0] + rect2.w < rect1.xy[0] + rect1.w):\n",
|
|
" remains.append(Rect((rect2.xy[0] + rect2.w, rect1.xy[1]), (rect1.xy[0] + rect1.w) - (rect2.xy[0] + rect2.w), rect1.h))\n",
|
|
" if (rect2.xy[1] > rect1.xy[1]):\n",
|
|
" remains.append(Rect(rect1.xy, rect1.w, rect2.xy[1] - rect1.xy[1]))\n",
|
|
" if (rect2.xy[1] + rect2.h < rect1.xy[1] + rect1.h):\n",
|
|
" remains.append(Rect((rect1.xy[0], rect2.xy[1] + rect2.h), rect1.w, (rect1.xy[1] + rect1.h) - (rect2.xy[1] + rect2.h)))\n",
|
|
" return remains\n",
|
|
"\n",
|
|
"def substract_rects(a, b):\n",
|
|
" a_coords = a.get_bbox()\n",
|
|
" b_coords = b.get_bbox()\n",
|
|
"\n",
|
|
" result_rects = []\n",
|
|
"\n",
|
|
" if a_coords.xmax > b_coords.xmin and a_coords.xmin < b_coords.xmax and a_coords.ymax > b_coords.ymin and a_coords.ymin < b_coords.ymax:\n",
|
|
" if a_coords.xmin < b_coords.xmin:\n",
|
|
" result_rect = Rect((a_coords.xmin, a_coords.ymin), b_coords.xmin - a_coords.xmin, a_coords.ymax - a_coords.ymin)\n",
|
|
" result_rects.append(result_rect)\n",
|
|
" \n",
|
|
" if a_coords.xmax > b_coords.xmax:\n",
|
|
" result_rect = Rect((b_coords.xmax, a_coords.ymin), a_coords.xmax - b_coords.xmax, a_coords.ymax - a_coords.ymin)\n",
|
|
" result_rects.append(result_rect)\n",
|
|
" \n",
|
|
" if a_coords.ymin < b_coords.ymin:\n",
|
|
" result_rect = Rect((max(a_coords.xmin, b_coords.xmin), a_coords.ymin), min(a_coords.xmax, b_coords.xmax) - max(a_coords.xmin, b_coords.xmin), b_coords.ymin - a_coords.ymin)\n",
|
|
" result_rects.append(result_rect)\n",
|
|
" \n",
|
|
" if a_coords.ymax > b_coords.ymax:\n",
|
|
" result_rect = Rect((max(a_coords.xmin, b_coords.xmin), b_coords.ymax), min(a_coords.xmax, b_coords.xmax) - max(a_coords.xmin, b_coords.xmin), a_coords.ymax - b_coords.ymax)\n",
|
|
" result_rects.append(result_rect)\n",
|
|
"\n",
|
|
" return result_rects"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"best ratio: 2.0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# HIER DIE PARAMETER FESTLEGEN\n",
|
|
"\n",
|
|
"TOTAL_X = 10\n",
|
|
"TOTAL_Y = 20\n",
|
|
"AREAS = np.array([30, 50, 8, 12, 100])\n",
|
|
"\n",
|
|
"\n",
|
|
"assert (np.sum(AREAS) == TOTAL_X * TOTAL_Y)\n",
|
|
"\n",
|
|
"best_ratio = norm_ratio(TOTAL_X / TOTAL_Y)\n",
|
|
"print(f\"best ratio: {round(best_ratio,2)}\")\n",
|
|
"areas = np.sort(AREAS)[::-1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"A=100.0, x=0, y=10.0, width=10, height=10.0, ratio=1.0\n",
|
|
"A=50.0, x=0, y=0, width=5.0, height=10.0, ratio=2.0\n",
|
|
"A=30.0, x=5.0, y=0, width=5.0, height=6.0, ratio=1.2\n",
|
|
"A=12.0, x=5.0, y=7.6, width=5.0, height=2.4, ratio=2.083\n",
|
|
"A=8.0, x=5.0, y=6.0, width=5.0, height=1.6, ratio=3.125\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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K0EkRTwI33f06FEtWbJE+fn5bf5bv7GxUf3795ff79eVV16pP/3pTxo2bFjI8c3NzWpubrb7DQ0NEV03TszlckmSlixZoqFDh57m1fz4bdmyRffdd1/UHyeqQVi5cqXq6+t15513hhwzePBgLVq0SMOHD5fP59Nzzz2nUaNG6fPPP9eFF14YdE5RUZEef/zxKK0a4Rg6dKiuvPLK072MH73GxsYOeZyo/pbh1VdfVWZmpjweT8gxaWlpysnJUUpKisaMGaO33npLcXFxevnll0POKSgokM/ns9vevXujsXzgrBO1dwh79uzRBx98oLfeeiused27d9cVV1yhqqqqkGOcTqecTmd7lwjgB6L2DmHx4sXq27evbrrpprDmtbS0aPv27UpISIjSygCEEpUg+P1+LV68WNOmTVO3boFvQnJyclRQUGD358yZo/fff1//+c9/tHXrVt1xxx3as2eP7rnnnmgsDUAbovIjwwcffKDa2lrdfffdrc7V1taqS5f/dejrr7/WvffeK6/Xq/POO08jRozQ+vXrdemll0ZjaQDaEJUgjB8/XsaYoOfWrl0bsD937lzNnTs3GssAECa+ywDAIggALIIAwCIIACyCAMAiCAAsggDAIggALIIAwCIIACyCAMAiCAAsggDAIggALIIAwCIIACyCAMAiCAAsggDAiurf3IQfP/6i147x/b8MOZoIAk7J8b/s9Y477jjNK0EkEQSckuN/2esTTzyhpKSk07yaH7+dO3fqqaeeivrjEAS0y4033shf9toBysvLOyQIfKgIwCIIACyCAMAiCAAsggDAIggALIIAwCIIACyCAMAiCAAsggDAIggArIgHYfbs2XI4HAHbkCFD2pyzfPlyDRkyRDExMbr88su1evXqSC8LwEmIyjuEYcOGaf/+/XZbt25dyLHr169Xdna2pk+frm3btikrK0tZWVnasWNHNJYGoA1RCUK3bt3kdrvt1qdPn5BjX3jhBd1www165JFHNHToUD3xxBO68sorNW/evGgsDUAbohKEXbt2yePxaODAgZo6dapqa2tDjt2wYYPS09MDjmVkZGjDhg0h5zQ3N6uhoSFgA9B+EQ9CamqqiouLVVJSogULFqimpkbXXXedDh8+HHS81+tVfHx8wLH4+Hh5vd6Qj1FUVCSXy2W3xMTEiD4H4GwV8SBkZmZq8uTJGj58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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# ALGORITMUS 1: Iterative Zweiteilung\n",
|
|
"\n",
|
|
"rects = []\n",
|
|
"r = Rect((0, 0), TOTAL_X, TOTAL_Y)\n",
|
|
"\n",
|
|
"for a in areas:\n",
|
|
" def add_rect(xy, width, height):\n",
|
|
" new_rect = Rect(xy, width, height)\n",
|
|
" rects.append(new_rect)\n",
|
|
" print(new_rect)\n",
|
|
"\n",
|
|
" if np.abs(norm_ratio(r.w ** 2 / a) - best_ratio) < np.abs(norm_ratio(r.h ** 2 / a) - best_ratio):\n",
|
|
" if (choice([True, False])):\n",
|
|
" new_xy = r.xy\n",
|
|
" r.set_xy((r.xy[0], r.xy[1] + a / r.w))\n",
|
|
" else:\n",
|
|
" new_xy = (r.xy[0], r.xy[1] + r.h - a / r.w)\n",
|
|
" add_rect(new_xy, r.w, a / r.w)\n",
|
|
" r.h = r.h - a / r.w\n",
|
|
"\n",
|
|
" else:\n",
|
|
" if (choice([True, False])):\n",
|
|
" new_xy = r.xy\n",
|
|
" r.set_xy((r.xy[0] + a / r.h, r.xy[1]))\n",
|
|
" else:\n",
|
|
" new_xy = (r.xy[0] + r.w - a / r.h, r.xy[1])\n",
|
|
" add_rect(new_xy, a / r.h, r.h)\n",
|
|
" r.w = r.w - a / r.h\n",
|
|
"\n",
|
|
"fig, ax = plt.subplots(1)\n",
|
|
"ax.set_aspect('equal', adjustable='box')\n",
|
|
"ax.add_collection(PatchCollection(rects, facecolor='white', edgecolor='black'))\n",
|
|
"ax.set_xlim((0, TOTAL_X))\n",
|
|
"ax.set_ylim((0, TOTAL_Y))\n",
|
|
"plt.show()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"A=100.0, x=0, y=0, width=8.333, height=12.0, ratio=1.44\n",
|
|
"A=12.0, x=8.333, y=4.8, width=1.667, height=7.2, ratio=4.32\n",
|
|
"A=8.0, x=8.333, y=0.0, width=1.667, height=4.8, ratio=2.88\n",
|
|
"A=50.0, x=0.0, y=15.0, width=10.0, height=5.0, ratio=2.0\n",
|
|
"A=30.0, x=0, y=12.0, width=10, height=3.0, ratio=3.333\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# ALGORITHMUS 2: Rekursiv. Besseres Seitenverhältnis für die großen Quadrate\n",
|
|
"\n",
|
|
"rects = []\n",
|
|
"\n",
|
|
"def fit_a(areas, r):\n",
|
|
" assert (np.sum(areas) - round(r.w * r.h) < 1e-6)\n",
|
|
"\n",
|
|
" if (len(areas) == 1):\n",
|
|
" rects.append(r)\n",
|
|
" return\n",
|
|
"\n",
|
|
" a = areas[0]\n",
|
|
" areas = np.array(areas[1:])\n",
|
|
"\n",
|
|
" res_ratio = 1000 * best_ratio\n",
|
|
" res_areas_top = []\n",
|
|
" res_areas_right = []\n",
|
|
" x_is_full_width = True\n",
|
|
"\n",
|
|
" for i in range(0, len(areas)):\n",
|
|
" mask = [bool(int(bit)) for bit in format(i, '0{}b'.format(len(areas)))]\n",
|
|
" areas_right = areas[mask]\n",
|
|
" areas_top = areas[[not bit for bit in mask]]\n",
|
|
" ratio1 = (r.w - np.sum(areas_right) / r.h) ** 2 / a\n",
|
|
" ratio2 = a / (r.h - np.sum(areas_top) / r.w) ** 2\n",
|
|
"\n",
|
|
" res_areas_top = areas_top\n",
|
|
" res_areas_right = areas_right\n",
|
|
"\n",
|
|
" if np.abs(norm_ratio(ratio1) - best_ratio) < np.abs(norm_ratio(res_ratio) - best_ratio):\n",
|
|
" res_ratio = ratio1\n",
|
|
" x_is_full_width = False\n",
|
|
"\n",
|
|
" if np.abs(norm_ratio(ratio2) - best_ratio) < np.abs(norm_ratio(res_ratio) - best_ratio):\n",
|
|
" res_ratio = ratio2\n",
|
|
" x_is_full_width = True\n",
|
|
" \n",
|
|
" zufall = choice([1,2,3,4])\n",
|
|
" if (zufall == 1):\n",
|
|
" new_xy = r.xy\n",
|
|
" elif (zufall == 2):\n",
|
|
" new_xy = (r.xy[0] + r.w - np.sqrt(a * res_ratio), r.xy[1])\n",
|
|
" elif (zufall == 3):\n",
|
|
" new_xy = (r.xy[0], r.xy[1] + r.h - np.sqrt(a / res_ratio))\n",
|
|
" elif (zufall == 4):\n",
|
|
" new_xy = (r.xy[0] + r.w - np.sqrt(a * res_ratio), r.xy[1] + r.h - np.sqrt(a / res_ratio))\n",
|
|
"\n",
|
|
" new_rect = Rect(new_xy, np.sqrt(a * res_ratio), np.sqrt(a / res_ratio))\n",
|
|
" rects.append(new_rect)\n",
|
|
"\n",
|
|
" new_remains = difference(r, new_rect)\n",
|
|
" if (len(new_remains) == 1 and res_areas_right.size > 0):\n",
|
|
" fit_a(res_areas_right, new_remains[0])\n",
|
|
" return\n",
|
|
" elif (len(new_remains) == 1 and res_areas_top.size > 0):\n",
|
|
" fit_a(res_areas_top, new_remains[0])\n",
|
|
" return\n",
|
|
" elif (x_is_full_width):\n",
|
|
" assert(len(substract_rects(new_remains[0], new_remains[1])) == 1)\n",
|
|
" new_remains = [substract_rects(new_remains[0], new_remains[1])[0], new_remains[1]]\n",
|
|
" else:\n",
|
|
" assert(len(substract_rects(new_remains[1], new_remains[0])) == 1)\n",
|
|
" new_remains = [new_remains[0], substract_rects(new_remains[1], new_remains[0])[0]]\n",
|
|
" \n",
|
|
" fit_a(res_areas_right, new_remains[0])\n",
|
|
" fit_a(res_areas_top, new_remains[1])\n",
|
|
"\n",
|
|
" \n",
|
|
"fit_a(areas, Rect((0, 0), TOTAL_X, TOTAL_Y))\n",
|
|
"\n",
|
|
"\n",
|
|
"for rect in rects:\n",
|
|
" print(rect)\n",
|
|
"fig, ax = plt.subplots(1)\n",
|
|
"ax.set_aspect('equal', adjustable='box')\n",
|
|
"ax.add_collection(PatchCollection(rects, facecolor='white', edgecolor='black'))\n",
|
|
"ax.set_xlim((0, TOTAL_X))\n",
|
|
"ax.set_ylim((0, TOTAL_Y))\n",
|
|
"plt.show()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"'\\nres_remaining_right = Rectangle(\\n (r.xy[0] + r.w - np.sum(areas_right) / r.h, r.xy[1]),\\n np.sum(areas_right) / r.h,\\n r.h\\n )\\n res_remaining_top = Rectangle(\\n (r.xy[0], r.xy[1] + a / (r.w - np.sum(areas_right) / r.h)),\\n np.sum(areas_top) / r.h,\\n np.sum(areas_top) / (r.w - np.sum(areas_right) / r.h)\\n )\\n\\nres_remaining_right = Rectangle(\\n (r.xy[0] + a / (r.h - np.sum(areas_top) / r.w), r.xy[1]),\\n np.sum(areas_right) / (r.h - np.sum(areas_top) / r.w),\\n np.sum(areas_right) / r.w\\n )\\n res_remaining_top = Rectangle( #FIXME\\n (r.xy[0], r.xy[1] + a / (r.w - np.sum(areas_right) / r.h)),\\n np.sum(areas_right) / r.h,\\n np.sum(areas_top) / r.w - np.sum(areas_right)\\n )\\n\\ndef try_rect(new_rect, outer_rect):\\n nonlocal areas\\n\\n print(f\"try: {new_rect} - outer: {outer_rect}\")\\n\\n new_remains = []\\n for re in remains:\\n new_remains += difference(re, outer_rect)\\n new_remains += difference(outer_rect, new_rect)\\n\\n if len(new_remains) == 0:\\n print(\"Success\")\\n return [new_rect]\\n\\n if len(new_remains) < len(areas):\\n print(\"Call\")\\n rects = fit_a(i+1, new_remains)\\n if rects is not False:\\n rects.insert(0, new_rect)\\n return rects\\n\\n print(\"Fail in try_rect\")\\n return False\\n\\n # TODO: Auch hier random\\n if r.w > r.h:\\n best = Rect(r.xy, np.sqrt(a * best_ratio), np.sqrt(a / best_ratio))\\n else:\\n best = Rect(r.xy, np.sqrt(a / best_ratio), np.sqrt(a * best_ratio))\\n\\n res = try_rect(best, r)\\n if (res is not False):\\n return res\\n\\n if np.abs(norm_ratio(r.w ** 2 / a) - best_ratio) < np.abs(norm_ratio(r.h ** 2 / a) - best_ratio):\\n notbest = Rect(r.xy, r.w, a / r.w)\\n else:\\n notbest = Rect(r.xy, a / r.h, r.h)\\n\\n res = try_rect(notbest, r)\\n if (res is not False):\\n return res\\n\\n print(\"Fail in fit\")\\n return False\\n'"
|
|
]
|
|
},
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"\"\"\"\n",
|
|
"res_remaining_right = Rectangle(\n",
|
|
" (r.xy[0] + r.w - np.sum(areas_right) / r.h, r.xy[1]),\n",
|
|
" np.sum(areas_right) / r.h,\n",
|
|
" r.h\n",
|
|
" )\n",
|
|
" res_remaining_top = Rectangle(\n",
|
|
" (r.xy[0], r.xy[1] + a / (r.w - np.sum(areas_right) / r.h)),\n",
|
|
" np.sum(areas_top) / r.h,\n",
|
|
" np.sum(areas_top) / (r.w - np.sum(areas_right) / r.h)\n",
|
|
" )\n",
|
|
"\n",
|
|
"res_remaining_right = Rectangle(\n",
|
|
" (r.xy[0] + a / (r.h - np.sum(areas_top) / r.w), r.xy[1]),\n",
|
|
" np.sum(areas_right) / (r.h - np.sum(areas_top) / r.w),\n",
|
|
" np.sum(areas_right) / r.w\n",
|
|
" )\n",
|
|
" res_remaining_top = Rectangle( #FIXME\n",
|
|
" (r.xy[0], r.xy[1] + a / (r.w - np.sum(areas_right) / r.h)),\n",
|
|
" np.sum(areas_right) / r.h,\n",
|
|
" np.sum(areas_top) / r.w - np.sum(areas_right)\n",
|
|
" )\n",
|
|
"\n",
|
|
"def try_rect(new_rect, outer_rect):\n",
|
|
" nonlocal areas\n",
|
|
"\n",
|
|
" print(f\"try: {new_rect} - outer: {outer_rect}\")\n",
|
|
"\n",
|
|
" new_remains = []\n",
|
|
" for re in remains:\n",
|
|
" new_remains += difference(re, outer_rect)\n",
|
|
" new_remains += difference(outer_rect, new_rect)\n",
|
|
"\n",
|
|
" if len(new_remains) == 0:\n",
|
|
" print(\"Success\")\n",
|
|
" return [new_rect]\n",
|
|
"\n",
|
|
" if len(new_remains) < len(areas):\n",
|
|
" print(\"Call\")\n",
|
|
" rects = fit_a(i+1, new_remains)\n",
|
|
" if rects is not False:\n",
|
|
" rects.insert(0, new_rect)\n",
|
|
" return rects\n",
|
|
"\n",
|
|
" print(\"Fail in try_rect\")\n",
|
|
" return False\n",
|
|
"\n",
|
|
" # TODO: Auch hier random\n",
|
|
" if r.w > r.h:\n",
|
|
" best = Rect(r.xy, np.sqrt(a * best_ratio), np.sqrt(a / best_ratio))\n",
|
|
" else:\n",
|
|
" best = Rect(r.xy, np.sqrt(a / best_ratio), np.sqrt(a * best_ratio))\n",
|
|
"\n",
|
|
" res = try_rect(best, r)\n",
|
|
" if (res is not False):\n",
|
|
" return res\n",
|
|
"\n",
|
|
" if np.abs(norm_ratio(r.w ** 2 / a) - best_ratio) < np.abs(norm_ratio(r.h ** 2 / a) - best_ratio):\n",
|
|
" notbest = Rect(r.xy, r.w, a / r.w)\n",
|
|
" else:\n",
|
|
" notbest = Rect(r.xy, a / r.h, r.h)\n",
|
|
"\n",
|
|
" res = try_rect(notbest, r)\n",
|
|
" if (res is not False):\n",
|
|
" return res\n",
|
|
"\n",
|
|
" print(\"Fail in fit\")\n",
|
|
" return False\n",
|
|
"\"\"\"\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "venv",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.8.10"
|
|
},
|
|
"orig_nbformat": 4
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|