unsupervised_learning_simul.../src/App.vue

1176 lines
32 KiB
Vue
Raw Normal View History

2023-09-15 10:04:05 +02:00
<template>
2023-09-15 21:56:16 +02:00
<div>
2023-09-15 10:04:05 +02:00
<img
id="kein_bild"
2023-09-15 21:56:16 +02:00
src="./assets/img/weiss_pixel.png"
2023-09-15 10:04:05 +02:00
style="width: 0px; height: 0px"
/>
<img
2023-09-15 21:56:16 +02:00
id="stadtplan"
src="./assets/img/stadtplan.png"
2023-09-15 10:04:05 +02:00
style="width: 0px; height: 0px"
/>
<img
id="gold_rush"
2023-09-15 21:56:16 +02:00
src="./assets/img/desert_landscape.png"
2023-09-15 10:04:05 +02:00
style="width: 0px; height: 0px"
/>
<h2>
Finde heraus, wie die Positionen der {{ this.bezeichnung_prototypen }} an
die {{ this.bezeichnung_datenpunkte }} angepasst werden.
</h2>
<br />
<canvas
id="c"
STYLE="border: 1px black solid;"
2023-09-15 21:56:16 +02:00
height="450"
2023-09-15 10:04:05 +02:00
width="800"
></canvas>
<br />
Die <b>Punkte</b> auf der Karte sind die
<b>{{ this.bezeichnung_datenpunkte }}</b
>.<br />
Die <b>x-Markierungen</b> auf der Karte entsprechen den
<b>{{ this.bezeichnung_prototypen }}</b
>
<br />
<br />
<div>
<button class="btn btn-primary" @click="starte_animation_alle">
starte Animation für alles
</button>
<input
type="range"
v-model="animation_speed_range"
min="0"
max="2000"
step="1"
/>
{{ animation_speed }} ms
</div>
<br />
<div>
<button class="btn btn-primary" @click="szenario_zuruecksetzen">
Szenario zurücksetzen
</button>
</div>
2023-09-15 10:04:05 +02:00
<br />
<div style="width: 800px; margin: auto">
<button class="btn btn-primary collapsible" style="background: grey">
Hilfekarte: Animation im Einzelschritt
</button>
<div class="content" id="content2">
<div class="row">
<div class="column">
{{ this.bezeichnung_aktueller_datenpunkt }}:
<button class="btn btn-primary" @click="voriger_datenpunkt">-</button>
&nbsp;<b style="font-size: x-large">{{ aktueller_datenpunkt + 1 }}</b
2023-09-15 10:04:05 +02:00
>&nbsp;
<button class="btn btn-primary" @click="naechster_datenpunkt">
2023-09-15 10:04:05 +02:00
+
</button>
</div>
<div class="column">
{{ this.bezeichnung_aktueller_prototyp }}:
2023-09-15 21:56:16 +02:00
<!-- <button @click="voriger_prototyp">-</button> -->
<b style="font-size: x-large">{{ aktueller_prototyp + 1}}</b>
2023-09-15 21:56:16 +02:00
<!-- <button @click="naechster_prototyp">+</button> -->
2023-09-15 10:04:05 +02:00
</div>
</div>
<button class="btn btn-primary" @click="starte_animation">
starte Animation nur für {{ this.bezeichnung_aktueller_datenpunkt }}
</button>
</div>
</div>
<br />
<div style="width: 800px; margin: auto">
<button class="btn btn-primary collapsible" style="background: grey">
Vertiefung: weitere Einstellungsmöglichkeiten
</button>
<div class="content" id="content0" style="text-align: center">
<br>
Verändere die Zahl der {{ this.bezeichnung_datenpunkte }} und {{ this.bezeichnung_prototypen }}.
<div class="row">
<div class="column" style="text-align: center">
<h3>{{ this.bezeichnung_datenpunkte }}</h3>
<button
class="btn btn-primary"
2023-09-15 21:56:16 +02:00
@click="update_anzahl_datenpunkte(--this.anzahl_datenpunkte)"
2023-09-15 10:04:05 +02:00
>
-
</button>
&nbsp;
2023-09-15 21:56:16 +02:00
<b style="font-size: xx-large">{{ this.anzahl_datenpunkte }}</b
2023-09-15 10:04:05 +02:00
>&nbsp;
<button
class="btn btn-primary"
2023-09-15 21:56:16 +02:00
@click="update_anzahl_datenpunkte(++this.anzahl_datenpunkte)"
2023-09-15 10:04:05 +02:00
>
+
</button>
<br />
<br />
<button class="btn btn-primary collapsible" style="background: grey">
manuell verändern
</button>
<div class="content" id="content1" style="text-align: left">
In jeder Zeile wird ein Datenpunkt mit den zugehörigen Werten
dargestellt:<br /><br />
<b>&nbsp;&nbsp;&nbsp; x; y</b><br />
<textarea
v-model="txt_datensatz"
placeholder="add multiple lines"
rows="10"
></textarea>
<br />
<button class="btn btn-primary" @click="textarea_2_datensatz">
Datenpunkte verändern
</button>
</div>
</div>
<div class="column" style="text-align: center">
<h3>{{ this.bezeichnung_prototypen }}</h3>
<button
class="btn btn-primary"
2023-09-15 21:56:16 +02:00
@click="update_anzahl_prototypen(--this.anzahl_prototypen)"
2023-09-15 10:04:05 +02:00
>
-
</button>
&nbsp;
2023-09-15 21:56:16 +02:00
<b style="font-size: xx-large">{{ this.anzahl_prototypen }}</b>
2023-09-15 10:04:05 +02:00
&nbsp;
<button
class="btn btn-primary"
2023-09-15 21:56:16 +02:00
@click="update_anzahl_prototypen(++this.anzahl_prototypen)"
2023-09-15 10:04:05 +02:00
>
+</button
2023-09-16 16:42:48 +02:00
> <br />
2023-09-15 10:04:05 +02:00
<br />
2023-09-16 16:42:48 +02:00
<button class="btn btn-primary collapsible" style="background: grey">
manuell verändern
</button>
<div class="content" id="content2" style="text-align: left">
In jeder Zeile wird ein Protoyp mit den zugehörigen Werten
dargestellt:<br /><br />
<b>&nbsp;&nbsp;&nbsp; x; y</b><br />
<textarea
v-model="txt_prototypensatz"
placeholder="add multiple lines"
rows="10"
></textarea>
<br />
<button class="btn btn-primary" @click="textarea_2_prototypensatz">
Prototypen verändern
</button>
</div>
2023-09-15 10:04:05 +02:00
</div>
</div>
<hr />
2023-09-15 21:56:16 +02:00
<div style="text-align: center">
2023-09-15 10:04:05 +02:00
<h3>Szenario auswählen</h3>
<select v-model="szenario" @change="szenario_aendern">
<option value="gold_rush">
Karte Gold Rush (Goldstücke und Ausgrabungsteams)
</option>
2023-09-15 21:56:16 +02:00
<option value="stadtplan">
Stadtplan (Haushalte und U-Bahn-Stationen)
2023-09-15 10:04:05 +02:00
</option>
<option value="kein_bild">reine Datenansicht</option>
</select>
</div>
2023-09-15 10:04:05 +02:00
<br />
</div>
</div>
<br />
<br />
2023-09-15 21:56:16 +02:00
</div>
2023-09-15 10:04:05 +02:00
</template>
<script>
2023-09-15 21:56:16 +02:00
// Import the generateDifferentColors function from generateColors.js
import { generateDifferentColors } from './generateColors.js'
2023-09-15 10:04:05 +02:00
export default {
name: "App",
components: {
// Zeichnung,
//HelloWorld
},
data() {
return {
2023-09-15 21:56:16 +02:00
datenpunkte_zufall: false,
2023-09-15 10:04:05 +02:00
txt_datensatz: null,
2023-09-16 16:42:48 +02:00
txt_prototypensatz: null,
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
anzahl_datenpunkte: 8,
anzahl_prototypen: 3,
2023-09-15 10:04:05 +02:00
szenario: "gold_rush",
2023-09-15 21:56:16 +02:00
gold_rush_datenpunkte: [
2023-09-15 10:04:05 +02:00
{ x: 2, y: 3, color: "black" },
{ x: 3, y: 6, color: "black" },
{ x: 4, y: 7, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
{ x: 300, y: 300, color: "black" },
],
2023-09-15 21:56:16 +02:00
datenpunkte: [
2023-09-15 10:04:05 +02:00
{ x: 300, y: 300, color: "black" },
{ x: 202, y: 70, color: "black" },
{ x: 162, y: 250, color: "black" },
{ x: 82, y: 20, color: "black" },
{ x: 500, y: 350, color: "black" },
{ x: 630, y: 170, color: "black" },
{ x: 430, y: 270, color: "black" },
{ x: 570, y: 30, color: "black" },
],
2023-09-15 21:56:16 +02:00
prototypen: [
2023-09-15 10:04:05 +02:00
{ x: 540, y: 50, color: "blue" },
{ x: 380, y: 370, color: "blue" },
{ x: 120, y: 150, color: "blue" },
],
prototypen_original: [
{ x: 540, y: 50, color: "blue" },
{ x: 380, y: 370, color: "blue" },
{ x: 120, y: 150, color: "blue" },
],
2023-09-15 10:04:05 +02:00
canvas: null,
vueCanvas: null,
2023-09-15 21:56:16 +02:00
aktueller_datenpunkt: 0,
aktueller_prototyp: 0,
2023-09-15 10:04:05 +02:00
animation_speed_range: 750,
paused: false,
animationsphase: null,
2023-09-15 21:56:16 +02:00
naechstgelegener_prototyp: null,
letzte_prototyp: null,
naechstgelegener_prototyp_distanz: null,
2023-09-15 10:04:05 +02:00
};
},
computed: {
aktuelles_hintergrundbild: function () {
return this.szenario;
},
bezeichnung_datenpunkte: function () {
switch (this.szenario) {
case "gold_rush":
return "Goldstücke";
2023-09-15 21:56:16 +02:00
case "stadtplan":
2023-09-15 10:04:05 +02:00
return "Haushalte";
}
return "Datenpunkte";
},
bezeichnung_prototypen: function () {
switch (this.szenario) {
case "gold_rush":
return "Grabungsteams";
2023-09-15 21:56:16 +02:00
case "stadtplan":
2023-09-15 10:04:05 +02:00
return "U-Bahn-Stationen";
}
return "Prototypen";
},
bezeichnung_aktueller_datenpunkt: function () {
switch (this.szenario) {
case "gold_rush":
return "aktuelles Goldstück";
2023-09-15 21:56:16 +02:00
case "stadtplan":
2023-09-15 10:04:05 +02:00
return "aktueller Haushalt";
}
return "aktueller Datenpunkt";
},
2023-09-15 21:56:16 +02:00
bezeichnung_aktueller_prototyp: function () {
2023-09-15 10:04:05 +02:00
switch (this.szenario) {
case "gold_rush":
return "aktuelles Grabungsteam";
2023-09-15 21:56:16 +02:00
case "stadtplan":
2023-09-15 10:04:05 +02:00
return "aktuelle U-Bahn-Station";
}
return "aktueller Prototyp";
},
animation_speed: function () {
return this.animation_speed_range * 1;
},
2023-09-15 21:56:16 +02:00
akt_datenpunkt: function () {
if (this.aktueller_datenpunkt < this.datenpunkte.length) {
return this.datenpunkte[this.aktueller_datenpunkt];
2023-09-15 10:04:05 +02:00
} else {
return null;
}
},
2023-09-15 21:56:16 +02:00
akt_prototyp: function () {
if (this.aktueller_prototyp < this.prototypen.length) {
return this.prototypen[this.aktueller_prototyp];
2023-09-15 10:04:05 +02:00
} else {
return null;
}
},
},
methods: {
lade() {
this.datensatz_2_textarea();
2023-09-16 16:42:48 +02:00
this.prototypensatz_2_textarea();
2023-09-15 10:04:05 +02:00
},
datensatz_2_textarea() {
let text_ausgabe = "";
2023-09-15 21:56:16 +02:00
for (let i = 0; i < this.datenpunkte.length; i++) {
2023-09-15 10:04:05 +02:00
text_ausgabe +=
2023-09-15 21:56:16 +02:00
this.datenpunkte[i].x + "; " + this.datenpunkte[i].y + "\n";
2023-09-15 10:04:05 +02:00
}
this.txt_datensatz = text_ausgabe;
},
textarea_2_datensatz() {
let text = this.txt_datensatz.replaceAll(" ", "");
text = text.replaceAll("\n", "#");
while (text.includes("##")) {
text = text.replaceAll("##", "#");
}
console.log(text);
let regex_korrekt = text.match("^((\\d)*;(\\d)*(#))*((\\d)*;(\\d)*)?$");
if (!regex_korrekt) {
2023-09-16 16:42:48 +02:00
console.log("DATENSATZ nicht korrekt!");
2023-09-15 10:04:05 +02:00
} else {
2023-09-16 16:42:48 +02:00
console.log("DATENSATZ korrekt!");
2023-09-15 10:04:05 +02:00
let zeilen = text.split("#");
let neuer_ds = [];
for (let i = 0; i < zeilen.length; i++) {
if (zeilen[i].includes(";")) {
let zeile = zeilen[i].split(";");
2023-09-16 16:42:48 +02:00
let ds = { x: parseInt(zeile[0]), y: parseInt(zeile[1]), color: "black" };
2023-09-15 10:04:05 +02:00
neuer_ds.push(ds);
}
}
2023-09-15 21:56:16 +02:00
this.datenpunkte = neuer_ds;
this.anzahl_datenpunkte = this.datenpunkte.length;
this.update_anzahl_datenpunkte(this.anzahl_datenpunkte);
2023-09-15 10:04:05 +02:00
}
},
2023-09-16 16:42:48 +02:00
prototypensatz_2_textarea() {
let text_ausgabe = "";
for (let i = 0; i < this.prototypen.length; i++) {
text_ausgabe +=
this.prototypen[i].x + "; " + this.prototypen[i].y + "\n";
}
this.txt_prototypensatz = text_ausgabe;
},
textarea_2_prototypensatz() {
let text = this.txt_prototypensatz.replaceAll(" ", "");
text = text.replaceAll("\n", "#");
while (text.includes("##")) {
text = text.replaceAll("##", "#");
}
console.log(text);
let regex_korrekt = text.match("^((\\d)*;(\\d)*(#))*((\\d)*;(\\d)*)?$");
if (!regex_korrekt) {
console.log("PROTOTYPENSATZ nicht korrekt!");
} else {
console.log("PROTOTYPENSATZ korrekt!");
let zeilen = text.split("#");
let neuer_ps = [];
for (let i = 0; i < zeilen.length; i++) {
if (zeilen[i].includes(";")) {
let zeile = zeilen[i].split(";");
let ps = { x: parseInt(zeile[0]), y: parseInt(zeile[1]), color: "blue" };
neuer_ps.push(ps);
}
}
this.prototypen = neuer_ps;
this.prototypen_original = neuer_ps;
this.anzahl_prototypen = this.prototypen.length;
this.update_anzahl_prototypen(this.anzahl_prototypen);
}
},
2023-09-15 10:04:05 +02:00
szenario_aendern() {
this.loesche_zeichenflaeche();
this.refresh();
},
2023-09-15 21:56:16 +02:00
update_anzahl_datenpunkte(new_value) {
2023-09-15 10:04:05 +02:00
if (new_value >= 0) {
console.log("angekommen." + new_value);
2023-09-15 21:56:16 +02:00
this.anzahl_datenpunkte = new_value;
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
while (this.datenpunkte.length > this.anzahl_datenpunkte) {
this.datenpunkte.pop();
2023-09-15 10:04:05 +02:00
}
2023-09-15 21:56:16 +02:00
while (this.datenpunkte.length < this.anzahl_datenpunkte) {
2023-09-16 16:42:48 +02:00
let neuer_datenpunkt = this.generiere_datenpunkt_zufaellig();
this.datenpunkte.push(neuer_datenpunkt);
2023-09-15 10:04:05 +02:00
}
//this.update_zeichnung_child_component();
this.datensatz_2_textarea();
this.refresh();
} else {
2023-09-15 21:56:16 +02:00
this.anzahl_datenpunkte = 0;
2023-09-15 10:04:05 +02:00
}
},
2023-09-15 21:56:16 +02:00
update_anzahl_prototypen(new_value) {
// Original Prototypen laden
2023-09-16 16:42:48 +02:00
console.log(this.prototypen_original);
console.log(this.prototypen);
this.prototypen = JSON.parse(JSON.stringify(this.prototypen_original))
2023-09-15 10:04:05 +02:00
if (new_value >= 0) {
console.log("angekommen." + new_value);
2023-09-15 21:56:16 +02:00
this.anzahl_prototypen = new_value;
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
while (this.prototypen.length > this.anzahl_prototypen) {
this.prototypen.pop();
2023-09-15 10:04:05 +02:00
}
2023-09-15 21:56:16 +02:00
while (this.prototypen.length < this.anzahl_prototypen) {
let neuer_prototyp = this.generiere_prototyp_zufaellig();
this.prototypen.push(neuer_prototyp);
2023-09-15 10:04:05 +02:00
}
//this.update_zeichnung_child_component();
2023-09-16 16:42:48 +02:00
this.prototypensatz_2_textarea();
2023-09-15 10:04:05 +02:00
this.refresh();
} else {
2023-09-15 21:56:16 +02:00
this.anzahl_prototypen = 0;
while (this.prototypen.length > this.anzahl_prototypen) {
this.prototypen.pop();
}
2023-09-15 10:04:05 +02:00
}
// Original Prototypen merken
this.prototypen_original = JSON.parse(JSON.stringify(this.prototypen))
2023-09-15 10:04:05 +02:00
},
/*
update_zeichnung_child_component() {
2023-09-15 21:56:16 +02:00
//this.$refs.component_zeichnung.update_anzahlen(this.datenpunkte, this.prototypen)
2023-09-15 10:04:05 +02:00
this.$refs.component_zeichnung.refresh();
2023-09-15 21:56:16 +02:00
console.log("update child sent" + this.datenpunkte.length);
2023-09-15 10:04:05 +02:00
},
*/
2023-09-15 21:56:16 +02:00
generiere_datenpunkt_zufaellig() {
2023-09-15 10:04:05 +02:00
let max_x = 800;
2023-09-15 21:56:16 +02:00
let max_y = 450;
let datenpunkt = {};
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
datenpunkt.x = Math.floor(Math.random() * max_x);
datenpunkt.y = Math.floor(Math.random() * max_y);
datenpunkt.color = "black";
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
console.log(datenpunkt);
return datenpunkt;
2023-09-15 10:04:05 +02:00
},
2023-09-15 21:56:16 +02:00
generiere_prototyp_zufaellig() {
2023-09-15 10:04:05 +02:00
let max_x = 800;
2023-09-15 21:56:16 +02:00
let max_y = 450;
let prototyp = {};
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
prototyp.x = Math.floor(Math.random() * max_x);
prototyp.y = Math.floor(Math.random() * max_y);
prototyp.color = "blue";
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
console.log(prototyp);
return prototyp;
2023-09-15 10:04:05 +02:00
},
zeichne_hintergrund() {
const bild = document.getElementById(this.aktuelles_hintergrundbild);
2023-09-15 21:56:16 +02:00
console.log("background image: " + this.aktuelles_hintergrundbild);
2023-09-15 10:04:05 +02:00
let bildX = 0;
let bildY = 0;
let breite = 800;
2023-09-15 21:56:16 +02:00
let hoehe = 450;
2023-09-15 10:04:05 +02:00
this.vueCanvas.drawImage(bild, bildX, bildY, breite, hoehe);
},
2023-09-15 21:56:16 +02:00
faerbe_prototypen() {
let anzahl = this.prototypen.length;
2023-09-15 10:04:05 +02:00
let farben = generateDifferentColors(anzahl);
//colors_generation;
console.log(anzahl + farben);
2023-09-15 21:56:16 +02:00
for (let i = 0; i < this.prototypen.length; i++) {
this.prototypen[i].color = farben[i];
console.log(this.prototypen[i].color);
2023-09-15 10:04:05 +02:00
}
},
faerbe_datenpunkte(alle) {
2023-09-15 21:56:16 +02:00
for (let i = 0; i < this.datenpunkte.length; i++) {
if (alle || i < this.aktueller_datenpunkt) {
let next_prototyp = this.gib_naechstgelegener_prototyp(this.datenpunkte[i]);
let farbe = next_prototyp.color;
this.datenpunkte[i].color = farbe;
2023-09-15 10:04:05 +02:00
console.log(farbe);
}
}
},
async refresh() {
return new Promise((resolve) => {
2023-09-15 21:56:16 +02:00
this.faerbe_prototypen();
2023-09-15 10:04:05 +02:00
this.loesche_zeichenflaeche();
this.zeichne_hintergrund();
2023-09-15 21:56:16 +02:00
this.zeichne_datenpunkte(false, true);
this.zeichne_prototypen(false);
2023-09-15 10:04:05 +02:00
setTimeout(() => {
resolve(); // Resolve the promise when the animation is done
}, this.animation_speed); // 1-second delay
});
},
loesche_zeichenflaeche() {
this.vueCanvas.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
zeichne_kreis(x, y, radius, fuellFarbe, randFarbe) {
let randDicke;
//randFarbe = 'black'
2023-09-15 21:56:16 +02:00
randDicke = Math.ceil(radius / 3);
2023-09-15 10:04:05 +02:00
this.vueCanvas.strokeStyle = randFarbe;
this.vueCanvas.beginPath();
this.vueCanvas.lineWidth = randDicke;
this.vueCanvas.arc(x, y, radius, 0, 2 * Math.PI);
this.vueCanvas.fillStyle = fuellFarbe;
this.vueCanvas.fill();
this.vueCanvas.stroke();
},
zeichne_x(x, y, color) {
let staerke = 4;
let groesse = 6;
//ctxBaum.fillStyle = color
this.vueCanvas.beginPath();
this.vueCanvas.moveTo(x + groesse, y + groesse);
this.vueCanvas.lineWidth = staerke;
// set line color
this.vueCanvas.strokeStyle = color;
this.vueCanvas.lineTo(x - groesse, y - groesse);
this.vueCanvas.moveTo(x - groesse, y + groesse);
this.vueCanvas.lineWidth = staerke;
// set line color
this.vueCanvas.strokeStyle = color;
this.vueCanvas.lineTo(x + groesse, y - groesse);
this.vueCanvas.stroke();
},
zeichne_linie(x1, y1, x2, y2, farbe, staerke) {
//ctxBaum.fillStyle = color
this.vueCanvas.beginPath();
this.vueCanvas.moveTo(x1, y1);
this.vueCanvas.lineWidth = staerke;
// set line color
this.vueCanvas.strokeStyle = farbe;
this.vueCanvas.lineTo(x2, y2);
this.vueCanvas.stroke();
},
zeichne_linie_datenpunkt_naechstgelegener_prototyp(datenpunkt) {
2023-09-15 10:04:05 +02:00
let farbe = "red";
let staerke = 2;
2023-09-15 21:56:16 +02:00
let prototyp = this.gib_naechstgelegener_prototyp(datenpunkt);
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
if (datenpunkt != null && prototyp != null) {
2023-09-15 10:04:05 +02:00
this.zeichne_linie(
2023-09-15 21:56:16 +02:00
datenpunkt.x,
datenpunkt.y,
prototyp.x,
prototyp.y,
2023-09-15 10:04:05 +02:00
farbe,
staerke
);
}
},
2023-09-15 21:56:16 +02:00
zeichne_linie_datenpunkt_prototyp(datenpunkt, prototyp, farbe, staerke) {
if (datenpunkt != null && prototyp != null) {
2023-09-15 10:04:05 +02:00
this.zeichne_linie(
2023-09-15 21:56:16 +02:00
datenpunkt.x,
datenpunkt.y,
prototyp.x,
prototyp.y,
2023-09-15 10:04:05 +02:00
farbe,
staerke
);
}
},
zeige_line_an() {
2023-09-15 21:56:16 +02:00
this.zeichne_linie_datenpunkt_prototyp(
this.datenpunkte[this.aktueller_datenpunkt],
this.prototypen[this.aktueller_prototyp]
2023-09-15 10:04:05 +02:00
);
},
2023-09-15 21:56:16 +02:00
zeichne_datenpunkte(markierung, zeichne_alle) {
2023-09-15 10:04:05 +02:00
let radius = 8;
let i = 0;
let hightlight_farbe = "lightgreen";
2023-09-15 21:56:16 +02:00
this.datenpunkte.forEach((element) => {
if (markierung && i == this.aktueller_datenpunkt) {
2023-09-15 10:04:05 +02:00
this.zeichne_kreis(
element.x,
element.y,
radius * 1.5,
hightlight_farbe,
hightlight_farbe
);
}
let kreis_farbe = element.color; //"black";
/*
2023-09-15 21:56:16 +02:00
if (i < this.aktueller_datenpunkt) {
2023-09-15 10:04:05 +02:00
kreis_farbe = element.color;
}
*/
2023-09-15 21:56:16 +02:00
if (zeichne_alle || i < this.aktueller_datenpunkt) {
2023-09-15 10:04:05 +02:00
this.zeichne_kreis(
element.x,
element.y,
radius,
kreis_farbe,
2023-09-15 21:56:16 +02:00
"white"
2023-09-15 10:04:05 +02:00
);
}
i++;
});
},
2023-09-15 21:56:16 +02:00
zeichne_prototypen(markierung) {
2023-09-15 10:04:05 +02:00
let i = 0;
let hightlight_farbe;
let radius;
2023-09-15 21:56:16 +02:00
this.prototypen.forEach((element) => {
2023-09-15 10:04:05 +02:00
hightlight_farbe = "white";
radius = 14;
2023-09-15 21:56:16 +02:00
if (markierung && i == this.aktueller_prototyp) {
2023-09-15 10:04:05 +02:00
hightlight_farbe = "lightgreen";
let radius_markierung = radius + 5;
this.zeichne_kreis(
element.x,
element.y,
radius_markierung,
"white",
hightlight_farbe
);
}
2023-09-15 21:56:16 +02:00
this.zeichne_kreis(element.x, element.y, radius, "white", element.color);
2023-09-15 10:04:05 +02:00
this.zeichne_x(element.x, element.y, element.color);
console.log(element.color);
i++;
});
},
naechster_datenpunkt() {
2023-09-15 21:56:16 +02:00
if (this.aktueller_datenpunkt < this.datenpunkte.length - 1) {
this.aktueller_datenpunkt++;
2023-09-15 10:04:05 +02:00
this.refresh();
2023-09-15 21:56:16 +02:00
this.zeichne_datenpunkte(true, true);
2023-09-15 10:04:05 +02:00
}
},
voriger_datenpunkt() {
2023-09-15 21:56:16 +02:00
if (this.aktueller_datenpunkt > 0) {
this.aktueller_datenpunkt--;
2023-09-15 10:04:05 +02:00
this.refresh();
2023-09-15 21:56:16 +02:00
this.zeichne_datenpunkte(true, true);
2023-09-15 10:04:05 +02:00
}
},
2023-09-15 21:56:16 +02:00
naechster_prototyp() {
this.aktueller_prototyp++;
2023-09-15 10:04:05 +02:00
this.refresh();
2023-09-15 21:56:16 +02:00
this.zeichne_prototypen(true);
2023-09-15 10:04:05 +02:00
},
2023-09-15 21:56:16 +02:00
voriger_prototyp() {
this.aktueller_prototyp--;
2023-09-15 10:04:05 +02:00
this.refresh();
2023-09-15 21:56:16 +02:00
this.zeichne_prototypen(true);
2023-09-15 10:04:05 +02:00
},
2023-09-15 21:56:16 +02:00
gib_distanz(datenpunkt, prototyp) {
let x1 = datenpunkt.x;
let y1 = datenpunkt.y;
let x2 = prototyp.x;
let y2 = prototyp.y;
2023-09-15 10:04:05 +02:00
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
},
2023-09-15 21:56:16 +02:00
gib_naechstgelegener_prototyp(datenpunkt) {
if (datenpunkt == null) {
2023-09-15 10:04:05 +02:00
return null;
}
2023-09-15 21:56:16 +02:00
let naechstgelegener_prototyp = null;
2023-09-15 10:04:05 +02:00
let min_distanz = null;
2023-09-15 21:56:16 +02:00
// pruefe alle prototypen und merke die naechste
for (let i = 0; i < this.prototypen.length; i++) {
let akt_prototyp = this.prototypen[i];
let akt_distanz = this.gib_distanz(datenpunkt, akt_prototyp);
if (naechstgelegener_prototyp == null || akt_distanz < min_distanz) {
naechstgelegener_prototyp = akt_prototyp;
2023-09-15 10:04:05 +02:00
min_distanz = akt_distanz;
}
}
2023-09-15 21:56:16 +02:00
return naechstgelegener_prototyp;
2023-09-15 10:04:05 +02:00
},
berechne_neue_pos_haelfte(x1, y1, x2, y2) {
let neue_pos = {
x: (x1 + x2) / 2,
y: (y1 + y2) / 2,
};
return neue_pos;
},
//////////////////////////////////////////
pausiere_animation() {
this.paused = true;
},
2023-09-15 21:56:16 +02:00
kurz_zeichne_linie_datenpunkt_prototyp() {
2023-09-15 10:04:05 +02:00
// pruefe_aktuelle
2023-09-15 21:56:16 +02:00
this.zeichne_linie_datenpunkt_prototyp(
this.akt_datenpunkt,
this.akt_prototyp,
2023-09-15 10:04:05 +02:00
"lightgreen",
4
);
},
existiert_kuerzere_Distanz() {
2023-09-15 21:56:16 +02:00
// bisher naechstgelegener Prototyp
2023-09-15 10:04:05 +02:00
let akt_distanz = this.gib_distanz(
2023-09-15 21:56:16 +02:00
this.akt_datenpunkt,
this.akt_prototyp
2023-09-15 10:04:05 +02:00
);
// naechsten aktualisieren
if (
2023-09-15 21:56:16 +02:00
this.naechstgelegener_prototyp == null ||
akt_distanz < this.naechstgelegener_prototyp_distanz
2023-09-15 10:04:05 +02:00
) {
2023-09-15 21:56:16 +02:00
this.naechstgelegener_prototyp = this.akt_prototyp;
this.naechstgelegener_prototyp_distanz = akt_distanz;
2023-09-15 10:04:05 +02:00
return true;
} else {
return false;
}
},
verarbeite_kuerzere_distanz() {
if (this.existiert_kuerzere_Distanz()) {
this.zeichne_kuerzeste_Distanz();
}
},
kurz_zeichne_linie_datenpunkt_naechstgelegener_prototyp() {
2023-09-15 21:56:16 +02:00
this.zeichne_linie_datenpunkt_prototyp(
this.akt_datenpunkt,
this.naechstgelegener_prototyp,
2023-09-15 10:04:05 +02:00
"red",
3
);
},
async starte_animation_alle() {
this.loesche_zeichenflaeche();
2023-09-15 21:56:16 +02:00
this.aktueller_datenpunkt = 0;
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
for (let i = 0; i < this.datenpunkte.length; i++) {
this.aktueller_datenpunkt = i;
2023-09-15 10:04:05 +02:00
await this.starte_animation();
}
this.faerbe_datenpunkte(true);
2023-09-15 10:04:05 +02:00
this.loesche_zeichenflaeche();
this.zeichne_hintergrund();
2023-09-15 21:56:16 +02:00
this.zeichne_datenpunkte(false, true);
this.zeichne_prototypen(false);
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
//this.zeige_naechsten_bekannten_prototyp();
2023-09-15 10:04:05 +02:00
},
async starte_animation() {
2023-09-15 21:56:16 +02:00
this.aktueller_prototyp = 0;
this.naechstgelegener_prototyp = null;
this.naechstgelegener_prototyp_distanz = null;
2023-09-15 10:04:05 +02:00
this.paused = false;
await this.mainAnimationLoop();
},
async mainAnimationLoop() {
// Call the first animation and wait for it to finish
2023-09-15 21:56:16 +02:00
let alle_prototypen_verarbeitet = false;
while (!alle_prototypen_verarbeitet) {
2023-09-15 10:04:05 +02:00
this.zeichne_hintergrund();
this.faerbe_datenpunkte(false);
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
if (this.aktueller_prototyp == 0) {
this.zeichne_datenpunkte(false, true);
await this.zeichne_prototypen(false);
2023-09-15 10:04:05 +02:00
}
2023-09-15 21:56:16 +02:00
await this.zeige_prototyp();
await this.zeige_naechsten_bekannten_prototyp();
2023-09-15 10:04:05 +02:00
if (this.existiert_kuerzere_Distanz()) {
this.loesche_zeichenflaeche();
this.zeichne_hintergrund();
2023-09-15 21:56:16 +02:00
this.zeichne_datenpunkte(false, true);
this.zeichne_prototypen(false);
await this.zeige_naechsten_bekannten_prototyp();
2023-09-15 10:04:05 +02:00
}
2023-09-15 21:56:16 +02:00
if (this.aktueller_prototyp < this.prototypen.length) {
if (this.aktueller_prototyp == this.prototypen.length - 1) {
alle_prototypen_verarbeitet = true;
2023-09-15 10:04:05 +02:00
} else {
2023-09-15 21:56:16 +02:00
this.aktueller_prototyp++;
2023-09-15 10:04:05 +02:00
}
}
}
// Schlussbild
this.loesche_zeichenflaeche();
this.faerbe_datenpunkte(false);
2023-09-15 21:56:16 +02:00
this.zeichne_datenpunkte(false, true);
this.zeichne_prototypen(false);
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
this.zeige_naechsten_bekannten_prototyp();
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
// prototyp verschieben
await this.aktualisiere_pos_prototyp();
2023-09-15 10:04:05 +02:00
},
async pausiere(zeitspanne) {
return new Promise((resolve) => {
// nichts tun
// Simulate some delay (you can replace this with actual animation code)
setTimeout(() => {
resolve(); // Resolve the promise when the animation is done
}, zeitspanne); // delay for zeitspanne
2023-09-15 10:04:05 +02:00
});
},
2023-09-15 21:56:16 +02:00
zeige_prototyp() {
2023-09-15 10:04:05 +02:00
return new Promise((resolve) => {
// Your animation code here
//this.loesche_zeichenflaeche();
2023-09-15 21:56:16 +02:00
this.kurz_zeichne_linie_datenpunkt_prototyp();
this.zeige_naechsten_bekannten_prototyp();
this.zeichne_datenpunkte(true, true);
this.zeichne_prototypen(true);
2023-09-15 10:04:05 +02:00
// Simulate some delay (you can replace this with actual animation code)
setTimeout(() => {
resolve(); // Resolve the promise when the animation is done
}, this.animation_speed); // 1-second delay
});
},
2023-09-15 21:56:16 +02:00
zeige_naechsten_bekannten_prototyp() {
2023-09-15 10:04:05 +02:00
return new Promise((resolve) => {
// Your animation code here
2023-09-15 21:56:16 +02:00
if (this.naechstgelegener_prototyp != null && this.akt_datenpunkt != null) {
this.kurz_zeichne_linie_datenpunkt_naechstgelegener_prototyp();
2023-09-15 21:56:16 +02:00
this.zeichne_datenpunkte(true, true);
this.zeichne_prototypen(true);
2023-09-15 10:04:05 +02:00
}
// Simulate some delay (you can replace this with actual animation code)
setTimeout(() => {
resolve(); // Resolve the promise when the animation is done
}, this.animation_speed); // 1-second delay
});
},
2023-09-15 21:56:16 +02:00
aktualisiere_pos_prototyp() {
2023-09-15 10:04:05 +02:00
return new Promise((resolve) => {
this.faerbe_datenpunkte(false);
2023-09-15 21:56:16 +02:00
this.animieren();
2023-09-15 10:04:05 +02:00
setTimeout(() => {
resolve(); // Resolve the promise when the animation is done
}, this.animation_speed * 2);
});
},
2023-09-15 21:56:16 +02:00
async animieren() {
this.letzte_prototyp = this.naechstgelegener_prototyp;
2023-09-15 10:04:05 +02:00
let schritte = 50;
if (this.animation_speed < 10) {
schritte = 1;
}
let i = 0;
2023-09-15 21:56:16 +02:00
let x_neu = (this.akt_datenpunkt.x + this.naechstgelegener_prototyp.x) / 2;
let y_neu = (this.akt_datenpunkt.y + this.naechstgelegener_prototyp.y) / 2;
2023-09-15 10:04:05 +02:00
let delta_x =
2023-09-15 21:56:16 +02:00
(this.akt_datenpunkt.x - this.naechstgelegener_prototyp.x) / 2 / schritte;
2023-09-15 10:04:05 +02:00
let delta_y =
2023-09-15 21:56:16 +02:00
(this.akt_datenpunkt.y - this.naechstgelegener_prototyp.y) / 2 / schritte;
2023-09-15 10:04:05 +02:00
// zeichnen definieren
var draw = () => {
try {
2023-09-15 21:56:16 +02:00
this.naechstgelegener_prototyp.x += delta_x;
this.naechstgelegener_prototyp.y += delta_y;
2023-09-15 10:04:05 +02:00
this.loesche_zeichenflaeche();
this.zeichne_hintergrund();
this.kurz_zeichne_linie_datenpunkt_naechstgelegener_prototyp();
2023-09-15 10:04:05 +02:00
2023-09-15 21:56:16 +02:00
this.zeichne_datenpunkte(true, true);
this.zeichne_prototypen(true);
2023-09-15 10:04:05 +02:00
i++;
if (i < schritte) {
//timestamp = Date.now();
requestAnimationFrame(draw);
} else {
2023-09-15 21:56:16 +02:00
this.naechstgelegener_prototyp.x = x_neu;
this.naechstgelegener_prototyp.y = y_neu;
2023-09-15 10:04:05 +02:00
this.refresh();
}
} catch (error) {
//console.error("Caught custom exception:", error.message);
2023-09-15 21:56:16 +02:00
this.letzte_prototyp.x = x_neu;
this.letzte_prototyp.y = y_neu;
2023-09-15 10:04:05 +02:00
this.refresh();
}
};
// Zeichnen aufrufen
draw();
},
szenario_zuruecksetzen() {
this.update_anzahl_datenpunkte(this.anzahl_datenpunkte);
this.update_anzahl_prototypen(this.anzahl_prototypen);
this.aktueller_datenpunkt = 0;
for (let i = 0; i < this.datenpunkte.length; i++) {
let next_prototyp = this.gib_naechstgelegener_prototyp(this.datenpunkte[i]);
this.datenpunkte[i].color = "#000000";
}
this.loesche_zeichenflaeche();
this.refresh();
this.zeichne_hintergrund();
this.zeichne_prototypen(false);
this.zeichne_datenpunkte(false, true);
console.log("Page completed with image and files!");
},
2023-09-15 10:04:05 +02:00
},
mounted() {
var c = document.getElementById("c");
var ctx = c.getContext("2d");
this.canvas = c;
this.vueCanvas = ctx;
2023-09-15 21:56:16 +02:00
this.aktueller_prototyp = 0;
2023-09-15 10:04:05 +02:00
this.lade();
2023-09-15 21:56:16 +02:00
this.update_anzahl_datenpunkte(this.anzahl_datenpunkte);
this.update_anzahl_prototypen(this.anzahl_prototypen);
2023-09-15 10:04:05 +02:00
document.onreadystatechange = () => {
if (document.readyState == "complete") {
this.refresh();
this.zeichne_hintergrund();
2023-09-15 21:56:16 +02:00
this.zeichne_prototypen(false);
this.zeichne_datenpunkte(false, true);
2023-09-15 10:04:05 +02:00
console.log("Page completed with image and files!");
// fetch to next page or some code
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function () {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
let content0 = document.getElementById("content0");
let content1 = document.getElementById("content1");
if (content == content1) {
console.log("gefunden");
content0.style.maxHeight =
content0.scrollHeight + content.scrollHeight + "px";
}
}
});
}
}
};
},
};
//------------------------------------------------------------
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
* {
box-sizing: border-box;
}
.row {
display: flex;
}
/* Create two equal columns that sits next to each other */
.column {
flex: 50%;
padding: 10px;
/* border: solid black 1px;
/*height: 300px; /* Should be removed. Only for demonstration */
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.active,
.collapsible:hover {
background-color: #555;
}
.collapsible:after {
content: "\002B";
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2212";
}
.content {
padding: 0 18px;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
background-color: #f1f1f1;
}
.btn {
display: inline-block;
font-weight: 400;
color: #212529;
text-align: center;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: 1rem;
line-height: 1.5;
border-radius: 0.25rem;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.btn:not(:disabled):not(.disabled) {
cursor: pointer;
}
.btn-primary {
color: #fff;
background-color: #007bff;
border-color: #007bff;
}
</style>