JSFiddle - React, Tailwind, and code Playground
by malikzh
HTML
<div class="cnv">
<canvas width="200" id="cmap" height="200"></canvas>
</div>
<div class="params">
<div class="param">
<div>
alpha
</div>
<div>
<input type="number" id="v-alpha" value="0.1" step="0.01">
</div>
</div>
<div class="param">
<div>
epsilon
</div>
<div>
<input type="number" id="v-epsilon" value="0.1" step="0.01">
</div>
</div>
<div class="param">
<div>
gamma
</div>
<div>
<input type="number" id="v-gamma" value="0.9" 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>
<div style="margin-top: 20px;">
Карта расстояний:
</div>
<canvas id="dmap" width="200" height="200"></canvas>
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 = 0x7F;
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));
}
}
// BL -> TL : V
for (let i=BL.y; i<=TL.y; ++i) {
const color = map.getColor(BL.x, i);
if (avg(color) >= THRESHOLD) {
dist = Math.min(dist, norm(x - BL.x, y - i));
}
}
// BR -> TR : V
for (let i=BR.y; i<=TR.y; ++i) {
const color = map.getColor(BR.x, i);
if (avg(color) >= THRESHOLD) {
dist = Math.min(dist,...