mirror of
https://github.com/robonen/eulerian-cycle.git
synced 2026-03-20 19:04:48 +00:00
Update guide
This commit is contained in:
@@ -28,6 +28,10 @@ html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
@@ -529,3 +533,22 @@ p {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-left-enter-active {
|
||||
animation: fade-left 0.5s;
|
||||
}
|
||||
|
||||
.fade-left-leave-active {
|
||||
animation: fade-left 0.5s reverse;
|
||||
}
|
||||
|
||||
@keyframes fade-left {
|
||||
from {
|
||||
transform: translateX(40px);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,31 +103,33 @@ export default {
|
||||
// Watchers
|
||||
watch(
|
||||
() => props.currentStep,
|
||||
(stepId) => {
|
||||
if (loop === null) return;
|
||||
|
||||
// Invalidate all
|
||||
deactivateAll();
|
||||
|
||||
// Select passed
|
||||
for (let i = 0; i < stepId; i++) {
|
||||
const pass = loop[i];
|
||||
const pass_id = findLink(pass);
|
||||
|
||||
links.value[pass_id].selected = 2;
|
||||
wasActivatedNodes([pass.source, pass.target]);
|
||||
}
|
||||
|
||||
// Select current
|
||||
const current = loop[stepId];
|
||||
const current_id = findLink(current);
|
||||
|
||||
links.value[current_id].selected = 1;
|
||||
activateNodes([current.source, current.target]);
|
||||
}
|
||||
(stepId) => highlight(stepId)
|
||||
);
|
||||
|
||||
// Methods
|
||||
// Methodsc
|
||||
const highlight = (stepId) => {
|
||||
if (loop === null) return;
|
||||
|
||||
// Invalidate all
|
||||
deactivateAll();
|
||||
|
||||
// Select passed
|
||||
for (let i = 0; i < stepId; i++) {
|
||||
const pass = loop[i];
|
||||
const pass_id = findLink(pass);
|
||||
|
||||
links.value[pass_id].selected = 2;
|
||||
wasActivatedNodes([pass.source, pass.target]);
|
||||
}
|
||||
|
||||
// Select current
|
||||
const current = loop[stepId];
|
||||
const current_id = findLink(current);
|
||||
|
||||
links.value[current_id].selected = 1;
|
||||
activateNodes([current.source, current.target]);
|
||||
};
|
||||
|
||||
const loopPosition = (coords) => {
|
||||
const node = nodes.value[coords];
|
||||
|
||||
@@ -151,6 +153,7 @@ export default {
|
||||
|
||||
if (links.value.length > 0 && euler.check()) {
|
||||
loop = euler.find();
|
||||
highlight(0);
|
||||
} else {
|
||||
loop = null;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<span class="version">{{ currentStep + 1 }} / {{ steps.length }}</span>
|
||||
</template>
|
||||
<template v-slot:content>
|
||||
{{ steps[currentStep].content }}
|
||||
<p v-html="steps[currentStep].content"></p>
|
||||
</template>
|
||||
</popup>
|
||||
</template>
|
||||
@@ -29,16 +29,29 @@ export default {
|
||||
// Const
|
||||
const steps = [
|
||||
{
|
||||
name: "Создание вершин",
|
||||
name: "Создание графа",
|
||||
content:
|
||||
"Для создания новой вершины необходимо дважды нажать левую кнопку мыши",
|
||||
video: "/video/create.mp4",
|
||||
"Для создания нового графа, необходимо добавить вершины на рабочую область. Для этого необходимо дважды кликнуть левой кнопкой мыши по рабочей области.",
|
||||
},
|
||||
{
|
||||
name: "Связывание вершин",
|
||||
content:
|
||||
"Чтобы связать вершины, необходимо кликнуть левой кнопкой мыши по вершине, которую необходимо связать. Далее выбираются вершины, с которыми необходимо связать",
|
||||
video: "/video/linking.mp4",
|
||||
"После создания вершин, их необходимо связать между собой. Для этого один раз кликните по необходимой вершине, после чего она поменяет цвет. Теперь необходимо выбрать вершины, с которыми необходимо связать. Если вершина успешно привязана, то появится ребро. Чтобы снять выделение, кликните в пустое место рабочей области.",
|
||||
},
|
||||
{
|
||||
name: "Удаление вершин и ребер",
|
||||
content:
|
||||
"В случае, когда необходимо удалить вершину или ребро, то достаточно один раз кликнуть правой кнопкой мыши по элементу.",
|
||||
},
|
||||
{
|
||||
name: "Нахождение эйлерова цикла",
|
||||
content:
|
||||
"После любых действий над вершинами или ребрами, программа проверяет наличие эйлерова цикла. Если эйлеров цикл будет найден, то:<ul><li>В верхней части программы появится количество шагов цикла и текущий шаг.</li><li>В правой части программы появится последовательность вершин в эйлеровом цикле.</li><li>Станет доступна кнопка проигрывания анимации прохождения цикла по графу.</li>",
|
||||
},
|
||||
{
|
||||
name: "Элементы управления анимацией",
|
||||
content:
|
||||
"Когда эйлеров цикл будет найден, появится возможность проиграть анимацию прохождения цикла по графу. Для этого существуют элементы управления в нижней части программы. Также анимацию можно просмотреть, начиная с нужной вершины, кликнув на нужную вершину в правой панели программы.",
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="popup-el popup-text">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
<!-- <div class="popup-el popup-text gray">by Robonen</div> -->
|
||||
<slot name="footer"></slot>
|
||||
<div class="popup-el popup-button-cont">
|
||||
<div v-if="leftBtnText" class="popup-button" @click="leftBtn">
|
||||
{{ leftBtnText }}
|
||||
|
||||
@@ -6,11 +6,33 @@
|
||||
<span class="version">v0.2</span>
|
||||
</template>
|
||||
<template v-slot:content>
|
||||
<p>Алгоритм находит Эйлеров цикл в неориентированном графе.</p>
|
||||
<p>
|
||||
<b>Эйлеров цикл</b>
|
||||
— путь, проходящий по всем ребрам графа, и при этом только по
|
||||
одному разу.
|
||||
Перед запуском алгоритма необходимо проверить граф на эйлеровость, т.е.
|
||||
каждая вершина должна иметь четную степень. Чтобы построить Эйлеров
|
||||
цикл, нужно запустить алгоритм из любой вершины.
|
||||
</p>
|
||||
<p>
|
||||
Алгоритм напоминает поиск в глубину. Главное отличие состоит в том, что
|
||||
пройденными помечаются не вершины, а ребра графа.
|
||||
</p>
|
||||
<p>
|
||||
Начиная со стартовой вершины <b>v</b> строим путь, добавляя на каждом
|
||||
шаге не пройденное еще ребро, смежное с текущей вершиной. Вершины пути
|
||||
накапливаются в стеке <b>S</b>. Когда наступает такой момент, что для
|
||||
текущей вершины <b>w</b> все инцидентные ей ребра уже пройдены,
|
||||
записываем вершины из <b>S</b> в ответ, пока не встретим вершину,
|
||||
которой инцидентны не пройденные еще ребра. Далее продолжаем обход по не
|
||||
посещенным ребрам.
|
||||
</p>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<a href="https://github.com/robonen/" class="gray">
|
||||
<div class="popup-el popup-text">Автор — Робонен А.С.</div>
|
||||
</a>
|
||||
<a href="https://github.com/RomaFedoro" class="gray">
|
||||
<div class="popup-el popup-text">Дизайн — Фёдоров Р.М.</div>
|
||||
</a>
|
||||
</template>
|
||||
</popup>
|
||||
<div class="addition-cont menu">
|
||||
@@ -90,23 +112,26 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="addition-cont">
|
||||
<div v-if="stepExists" class="step-cont">
|
||||
<div
|
||||
class="step"
|
||||
v-for="(step, i) in steps"
|
||||
:key="i"
|
||||
:class="{
|
||||
'active-step': i === currentStepNumber || i === currentStepNumber + 1,
|
||||
'dynamic-active-step': played && i < currentStepNumber,
|
||||
'last-active-step': i === currentStepNumber + 1,
|
||||
}"
|
||||
@click="currentStepNumber = i"
|
||||
>
|
||||
{{ step.source }}
|
||||
<transition name="fade-left">
|
||||
<div v-if="stepExists" class="addition-cont">
|
||||
<div class="step-cont">
|
||||
<div
|
||||
class="step"
|
||||
v-for="(step, i) in steps"
|
||||
:key="i"
|
||||
:class="{
|
||||
'active-step':
|
||||
i === currentStepNumber || i === currentStepNumber + 1,
|
||||
'dynamic-active-step': played && i < currentStepNumber,
|
||||
'last-active-step': i === currentStepNumber + 1,
|
||||
}"
|
||||
@click="currentStepNumber = i"
|
||||
>
|
||||
{{ step.source }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
Reference in New Issue
Block a user