Snippets
Created by
cia_rana
last modified
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | <body>
<script>
function make_red(red_rate) {
return "#ff" + ("00" + Math.ceil((1.0 - red_rate) * 255).toString(16)).substr(-2).repeat(2);
}
function make_table(height, width, rate) {
var table = document.createElement("table");
table.setAttribute("id", "table");
table.setAttribute("bordercolor", "#333333");
table.setAttribute("cellspacing", "0");
document.body.appendChild(table);
for (let i = 0; i < height; i++) {
var row = table.insertRow();
for (let j = 0; j < width; j++) {
var td = document.createElement("td");
td.style.height = td.style.width = rate;
row.appendChild(td);
}
}
return table;
}
function get_points_argminmax(points) {
var point_length = points.length;
var argmin_x = [];
var argmin_y = [];
var argmax_x = [];
var argmax_y = [];
t = Number.MIN_VALUE;
for (let i = 0; i < point_length; i++) {
if (t < points[i].x) {
argmax_x = [i];
t = points[i].x;
} else if (t == points[i].x) {
argmax_x.push(i);
}
}
t = Number.MIN_VALUE;
for (let i = 0; i < point_length; i++) {
if (t < points[i].y) {
argmax_y = [i];
t = points[i].y;
} else if (t == points[i].y) {
argmax_y.push(i);
}
}
var t = Number.MAX_VALUE;
for (let i = 0; i < point_length; i++) {
if (t > points[i].x) {
argmin_x = [i];
t = points[i].x;
} else if (t == points[i].x) {
argmin_x.push(i);
}
}
t = Number.MAX_VALUE;
for (let i = 0; i < point_length; i++) {
if (t > points[i].y) {
argmin_y = [i];
t = points[i].y;
} else if (t == points[i].y) {
argmin_y.push(i);
}
}
return [argmin_x, argmin_y, argmax_x, argmax_y];
}
var Point = function(x, y) {
this.x = x;
this.y = y;
}
// 時計回りでかつ凸四角形の頂点
var points = [
new Point(15, 15),
new Point(30, 15),
new Point(40, 25),
new Point(12, 30)
];
var height = 50;
var width = 50;
var rate = 15;
var table = make_table(height, width, rate);
// 各辺を直角三角形の斜辺としたとき直角部分の頂点でかつ四角形の外側の点を抜き出す
var right_points = [];
for (let i = 0; i < 4; i++) {
var begin = points[i];
var end = points[(i + 1) % 4];
var cross = (begin.x - end.x) * (end.y - begin.y); // - 0 * (end.x - begin.x)
if (cross > 0) {
right_points.push(new Point(begin.x, end.y));
table.rows[end.y].cells[begin.x].setAttribute("bgcolor", make_red(0.5));
} else if (cross < 0) {
right_points.push(new Point(end.x, begin.y));
table.rows[begin.y].cells[end.x].setAttribute("bgcolor", make_red(0.5));
} else {
right_points.push(new Point(begin.x, begin.y));
}
}
// 四角形Tを内包する水平垂直な四角形Nの左上・右下の頂点の座標を持つ四角形Tの頂点を抜き出す
[argmin_x, argmin_y, argmax_x, argmax_y] = get_points_argminmax(points);
for (let y = points[argmin_y[0]].y, end_y = points[argmax_y[0]].y; y <= end_y; y++) {
var row = table.rows[y];
for (let x = points[argmin_x[0]].x, end_x = points[argmax_x[0]].x; x <= end_x; x++) {
row.cells[x].setAttribute("bgcolor", make_red(1));
}
}
// 四角形Nの辺に接していない四角形Tの頂点を抜き出し、その頂点に起因する不要な部分を四角形Nから削除する
args = argmin_x.concat(argmin_y)
.concat(argmax_x)
.concat(argmax_y)
.filter((x, i, self) => self.indexOf(x) === i);
nonargs = [0, 1, 2, 3].filter(x => args.indexOf(x) < 0);
for (let nonarg of nonargs) {
var right_point_pre = right_points[(nonarg + 3) % 4];
var right_point_now = right_points[nonarg];
var non_x, non_y;
if (right_point_pre.x === points[nonarg].x && right_point_now.y === points[nonarg].y) {
non_x = right_point_now.x;
non_y = right_point_pre.y;
} else {
non_x = right_point_pre.x;
non_y = right_point_now.y;
}
var start_x = Math.min.apply(null, [non_x, points[nonarg].x]);
var end_x = Math.max.apply(null, [non_x, points[nonarg].x]);
var start_y = Math.min.apply(null, [non_y, points[nonarg].y]);
var end_y = Math.max.apply(null, [non_y, points[nonarg].y]);
start_x === points[nonarg].x ? start_x++ : end_x--;
start_y === points[nonarg].y ? start_y++ : end_y--;
for (let y = start_y; y <= end_y; y++) {
for (let x = start_x; x <= end_x; x++) {
table.rows[y].cells[x].setAttribute("bgcolor", make_red(0));
}
}
}
for (let i = 0; i < 4; i++) {
var point_now = points[i];
var point_next = points[(i + 1) % 4];
var right_point = right_points[i];
var diff_x = point_now.x - point_next.x;
var diff_y = point_now.y - point_next.y;
if (diff_y === 0) {
continue;
}
var start_y = Math.min.apply(null, [point_now.y, point_next.y, right_point.y]);
var end_y = Math.max.apply(null, [point_now.y, point_next.y, right_point.y]);
var is_decrement_x = (right_point.x - point_next.x) > 1.0 * diff_x / diff_y * (right_point.y - point_next.y);
var start_x, end_x;
if (is_decrement_x) {
end_x = Math.max.apply(null, [point_now.x, point_next.x]);
} else {
start_x = Math.min.apply(null, [point_now.x, point_next.x]);
}
for (let y = start_y; y <= end_y; y++) {
if (is_decrement_x) {
start_x = Math.round(1.0 * diff_x / diff_y * (y - point_next.y) + point_next.x);
} else {
end_x = Math.round(1.0 * diff_x / diff_y * (y - point_next.y) + point_next.x);
}
var row = table.rows[y];
for (let x = start_x; x <= end_x; x++) {
row.cells[x].setAttribute("bgcolor", make_red(0));
}
}
}
for (let point of points) {
table.rows[point.y].cells[point.x].setAttribute("bgcolor", make_red(0.5));
}
for (let point of right_points) {
table.rows[point.y].cells[point.x].setAttribute("bgcolor", make_red(0.1));
}
</script>
</body>
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.