JSFiddle - React, Tailwind, and code Playground
by malikzh
HTML
<div class="cnv">
<canvas width="300" id="cmap" height="300"></canvas>
<canvas width="300" id="hmap" height="300" style="display: none;"></canvas>
<canvas width="300" id="qmap" height="300" style="display: block;"></canvas>
</div>
<div class="params">
<div class="param">
<div>
alpha
</div>
<div>
<input type="number" id="v-alpha" value="0.45" step="0.01">
</div>
</div>
<div class="param">
<div>
epsilon
</div>
<div>
<input type="number" id="v-epsilon" value="0.15" step="0.01">
</div>
</div>
<div class="param">
<div>
gamma
</div>
<div>
<input type="number" id="v-gamma" value="0.94" step="0.01">
</div>
</div>
<div class="param">
<button id="b-start">
Начать обучение
</button>
<button id="b-reset">
Сброс
</button>
</div>
</div>
<div style="margin-top: 10px;">
Типа консоль :)
</div>
<div id="our-console"></div>
CSS
canvas {
border: 1px solid #ccc;
}
.param {
margin-top: 20px;
}
#our-console {
width: 500px;
height: 250px;
overflow: scroll;
border: 1px solid #ccc;
font-family: monospace;
}
#our-console > div {
padding: 5px 0;
border-bottom: 1px solid #ccc;
}
JavaScript
// Теорема пифагора, только без корня, чтобы быстрее было
function norm(a, b) {
return a ** 2 + b ** 2;
}
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
}
scale(n) {
this.x *= n;
this.y *= n;
return this;
}
clamp(x0, y0, x1, y1) {
this.x = Math.min(x1, Math.max(x0, this.x));
this.y = Math.min(y1, Math.max(y0, this.y));
return this;
}
move(x, y) {
this.x += x;
this.y += y;
return this;
}
}
// Алгоритм поиска ближайшего расстояния маршрута в заданной точке заданной дистанции
function findNearest(map, x, y, d) {
const THRESHOLD = 0xFF;
const avg = (color) => Math.round((color[0] + color[1] + color[2]) / 3);
let dist = +Infinity;
// проверяем саму точку
if (avg(map.getColor(x, y)) >= THRESHOLD) {
return 0;
}
const TR = new Vector(1, -1).scale(d).move(x, y).clamp(0, 0, map.width(), map.height()); // top-right
const TL = new Vector(-1, -1).scale(d).move(x, y).clamp(0, 0, map.width(), map.height()); // top-left
const BR = new Vector(1, 1).scale(d).move(x, y).clamp(0, 0, map.width(), map.height()); // bottom-right
const BL = new Vector(-1, 1).scale(d).move(x, y).clamp(0, 0, map.width(), map.height()); // bottom-left
// TL -> TR : H
for (let i=TL.x; i<=TR.x; ++i) {
const color = map.getColor(i, TL.y);
if (avg(color) >= THRESHOLD) {
dist = Math.min(dist, norm(x - i, y - TL.y));
}
}
// BL -> BR : H
for (let i=BL.x; i<=BR.x; ++i) {
const color = map.getColor(i, BL.y);
if (avg(color) >= THRESHOLD) {
dist = Math.min(dist, norm(x - i, y - BL.y));
}
}
// TL -> BL : V
for (let i=TL.y; i<=BL.y; ++i) {
const color = map.getColor(TL.x, i);
if (avg(color) >= THRESHOLD) {
dist = Math.min(dist, norm(x - TL.x, y - i));
}
}
// TR -> BR : V
for (let i=TR.y; i<=BR.y; ++i) {
const color = map.getColor(TR.x, i);
if (avg(color) >= THRESHOLD) {
dist = Math.min(dist,...