Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
vektor [2024/12/07 12:55] jango [Dot product] |
vektor [2024/12/07 17:32] (aktuell) jango [Vektor Visualisierung] |
||
---|---|---|---|
Zeile 110: | Zeile 110: | ||
{{vektor_definieren.png}} | {{vektor_definieren.png}} | ||
+ | =====Cross product===== | ||
+ | |||
+ | Das Kreuzprodukt zweier Vektoren im 3D-Raum ergibt einen Vektor, der senkrecht (orthogonal) auf beiden Eingangsvektoren steht. | ||
+ | |||
+ | |||
+ | Für zwei Vektoren | ||
+ | |||
+ | A = (a1, a2, a3) | ||
+ | B = (b1, b2, b3) | ||
- | Das bedeutet umgekehrt | + | im 3D-Raum lautet die Formel für das Cross-Produkt: |
< | < | ||
- | Von 5 nach -1 => -6 | + | | i, j, k | |
- | Von 1 nach 5 => 4 | + | A * B = | a1, a2, a3 | |
- | Von -2 nach 1 => 3 | + | | b1, b2, b3 | |
</ | </ | ||
- | **Merke:** | + | |
+ | Dabei sind i,j,k die Einheitsvektoren entlang der x-, y- und z-Achse. | ||
- | * if dot > 0 => deg < 90 | + | Die Berechnung erfolgt durch die Determinante der Matrix, die die Komponenten der beiden Vektoren enthält. |
- | * if dot == 0 => deg == 90 | + | |
- | * if dot < 0 => deg > 90 | + | <code> |
- | =====Cross product===== | + | A * B = ((a2 * b3 - a3 * b2), (a3 * b1 - a1 * b3), (a1 * b2 - a2 * b1)) |
+ | </code> | ||
+ | |||
+ | Das Cross-Produkt ergibt einen Vektor, der senkrecht auf der Ebene steht, die durch die beiden Vektoren A und B aufgespannt wird. | ||
+ | Die Länge des resultierenden Vektors entspricht der Fläche des Parallelogramms, | ||
- | Das Kreuzprodukt zweier Vektoren im 3D-Raum ergibt einen Vektor, der senkrecht (orthogonal) auf beiden Eingangsvektoren steht. | ||
{{kreuzprodukt.png}} | {{kreuzprodukt.png}} | ||
Zeile 152: | Zeile 165: | ||
https:// | https:// | ||
+ | |||
+ | =====Vektor Visualisierung===== | ||
+ | |||
+ | < | ||
+ | < | ||
+ | <html lang=" | ||
+ | < | ||
+ | <meta charset=" | ||
+ | <meta name=" | ||
+ | < | ||
+ | < | ||
+ | body { margin: 0; font-family: | ||
+ | canvas { display: block; } | ||
+ | .controls { | ||
+ | position: absolute; | ||
+ | top: 10px; | ||
+ | left: 10px; | ||
+ | z-index: 1; | ||
+ | background: rgba(255, 255, 255, 0.7); | ||
+ | padding: 15px; | ||
+ | width: 240px; | ||
+ | height: 90%; | ||
+ | overflow-y: auto; | ||
+ | } | ||
+ | .section { | ||
+ | margin-bottom: | ||
+ | } | ||
+ | .section h3 { | ||
+ | margin-top: 0; | ||
+ | } | ||
+ | .section input, .section button { | ||
+ | width: 100%; | ||
+ | margin-bottom: | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | <div class=" | ||
+ | <!-- Vektor Eingabe --> | ||
+ | <div class=" | ||
+ | < | ||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <button onclick=" | ||
+ | </ | ||
+ | |||
+ | <!-- Vektor Operationen --> | ||
+ | <div class=" | ||
+ | < | ||
+ | <button onclick=" | ||
+ | <button onclick=" | ||
+ | <button onclick=" | ||
+ | </ | ||
+ | |||
+ | <!-- Rotation der Szene --> | ||
+ | <div class=" | ||
+ | < | ||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | |||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | |||
+ | <label for=" | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | </ | ||
+ | |||
+ | <!-- Kamera Position und Rotation --> | ||
+ | <div class=" | ||
+ | < | ||
+ | <label for=" | ||
+ | <input type=" | ||
+ | |||
+ | <label for=" | ||
+ | <input type=" | ||
+ | |||
+ | <label for=" | ||
+ | <input type=" | ||
+ | |||
+ | <label for=" | ||
+ | <input type=" | ||
+ | |||
+ | <label for=" | ||
+ | <input type=" | ||
+ | |||
+ | <label for=" | ||
+ | <input type=" | ||
+ | |||
+ | <button onclick=" | ||
+ | <button onclick=" | ||
+ | </ | ||
+ | |||
+ | <!-- Ausgabe --> | ||
+ | <div class=" | ||
+ | <span id=" | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <script src=" | ||
+ | <script src=" | ||
+ | |||
+ | < | ||
+ | const scene = new THREE.Scene(); | ||
+ | const camera = new THREE.PerspectiveCamera(75, | ||
+ | const renderer = new THREE.WebGLRenderer(); | ||
+ | renderer.setSize(window.innerWidth, | ||
+ | document.body.appendChild(renderer.domElement); | ||
+ | |||
+ | const light = new THREE.AmbientLight(0x404040, | ||
+ | scene.add(light); | ||
+ | |||
+ | const directionalLight = new THREE.DirectionalLight(0xffffff, | ||
+ | directionalLight.position.set(5, | ||
+ | scene.add(directionalLight); | ||
+ | |||
+ | function zoomIn() { | ||
+ | if (camera.position.z > 1) { | ||
+ | camera.position.z -= 1; | ||
+ | renderer.render(scene, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function zoomOut() { | ||
+ | camera.position.z += 1; | ||
+ | renderer.render(scene, | ||
+ | } | ||
+ | |||
+ | let v1 = new THREE.Vector3(1, | ||
+ | let v2 = new THREE.Vector3(3, | ||
+ | |||
+ | let arrowV1, arrowV2, arrowResultant, | ||
+ | |||
+ | function createArrow(vector, | ||
+ | const arrowHelper = new THREE.ArrowHelper(vector.clone().normalize(), | ||
+ | scene.add(arrowHelper); | ||
+ | return arrowHelper; | ||
+ | } | ||
+ | |||
+ | function createAxisAndScale() { | ||
+ | var maxNum = 9999; | ||
+ | |||
+ | const xAxisGeometry = new THREE.BufferGeometry().setFromPoints([ | ||
+ | new THREE.Vector3(0, | ||
+ | new THREE.Vector3(maxNum, | ||
+ | ]); | ||
+ | const xAxisMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); | ||
+ | const xAxis = new THREE.Line(xAxisGeometry, | ||
+ | scene.add(xAxis); | ||
+ | |||
+ | const yAxisGeometry = new THREE.BufferGeometry().setFromPoints([ | ||
+ | new THREE.Vector3(0, | ||
+ | new THREE.Vector3(0, | ||
+ | ]); | ||
+ | const yAxisMaterial = new THREE.LineBasicMaterial({ color: 0x00ff00 }); | ||
+ | const yAxis = new THREE.Line(yAxisGeometry, | ||
+ | scene.add(yAxis); | ||
+ | |||
+ | const zAxisGeometry = new THREE.BufferGeometry().setFromPoints([ | ||
+ | new THREE.Vector3(0, | ||
+ | new THREE.Vector3(0, | ||
+ | ]); | ||
+ | const zAxisMaterial = new THREE.LineBasicMaterial({ color: 0x0000ff }); | ||
+ | const zAxis = new THREE.Line(zAxisGeometry, | ||
+ | scene.add(zAxis); | ||
+ | |||
+ | for (let i = 1; i <= maxNum; i++) { | ||
+ | const xMarker = new THREE.Mesh( | ||
+ | new THREE.SphereGeometry(0.1), | ||
+ | new THREE.MeshBasicMaterial({ color: 0xff0000 }) | ||
+ | ); | ||
+ | xMarker.position.set(i, | ||
+ | scene.add(xMarker); | ||
+ | |||
+ | const yMarker = new THREE.Mesh( | ||
+ | new THREE.SphereGeometry(0.1), | ||
+ | new THREE.MeshBasicMaterial({ color: 0x00ff00 }) | ||
+ | ); | ||
+ | yMarker.position.set(0, | ||
+ | scene.add(yMarker); | ||
+ | |||
+ | const zMarker = new THREE.Mesh( | ||
+ | new THREE.SphereGeometry(0.1), | ||
+ | new THREE.MeshBasicMaterial({ color: 0x0000ff }) | ||
+ | ); | ||
+ | zMarker.position.set(0, | ||
+ | scene.add(zMarker); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function updateVectors() { | ||
+ | v1.set( | ||
+ | parseFloat(document.getElementById(' | ||
+ | parseFloat(document.getElementById(' | ||
+ | parseFloat(document.getElementById(' | ||
+ | ); | ||
+ | |||
+ | v2.set( | ||
+ | parseFloat(document.getElementById(' | ||
+ | parseFloat(document.getElementById(' | ||
+ | parseFloat(document.getElementById(' | ||
+ | ); | ||
+ | |||
+ | scene.clear(); | ||
+ | |||
+ | createAxisAndScale(); | ||
+ | |||
+ | arrowV1 = createArrow(v1, | ||
+ | arrowV2 = createArrow(v2, | ||
+ | |||
+ | if (arrowResultant) scene.remove(arrowResultant); | ||
+ | if (arrowDifference) scene.remove(arrowDifference); | ||
+ | if (arrowCrossProduct) scene.remove(arrowCrossProduct); | ||
+ | |||
+ | displayVectorComponents(v1, | ||
+ | displayVectorComponents(v2, | ||
+ | |||
+ | renderer.render(scene, | ||
+ | } | ||
+ | |||
+ | function toggleResultant() { | ||
+ | if (arrowResultant) { | ||
+ | scene.remove(arrowResultant); | ||
+ | arrowResultant = null; | ||
+ | } else { | ||
+ | arrowResultant = createArrow(v1.clone().add(v2), | ||
+ | displayVectorComponents(v1.clone().add(v2), | ||
+ | renderer.render(scene, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function toggleDifference() { | ||
+ | if (arrowDifference) { | ||
+ | scene.remove(arrowDifference); | ||
+ | arrowDifference = null; | ||
+ | } else { | ||
+ | arrowDifference = createArrow(v1.clone().sub(v2), | ||
+ | displayVectorComponents(v1.clone().sub(v2), | ||
+ | renderer.render(scene, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function toggleCrossProduct() { | ||
+ | if (arrowCrossProduct) { | ||
+ | scene.remove(arrowCrossProduct); | ||
+ | arrowCrossProduct = null; | ||
+ | } else { | ||
+ | arrowCrossProduct = createArrow(v1.clone().cross(v2), | ||
+ | displayVectorComponents(v1.clone().cross(v2), | ||
+ | renderer.render(scene, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function displayVectorComponents(vector, | ||
+ | const output = document.getElementById(' | ||
+ | const outputText = `${label} - x: ${vector.x.toFixed(2)}, | ||
+ | output.textContent = outputText; | ||
+ | console.log(outputText); | ||
+ | } | ||
+ | |||
+ | /* | ||
+ | camera.position.x = document.getElementById(" | ||
+ | camera.position.y = document.getElementById(" | ||
+ | camera.position.z = document.getElementById(" | ||
+ | */ | ||
+ | |||
+ | function animate() { | ||
+ | requestAnimationFrame(animate); | ||
+ | |||
+ | scene.rotation.x = document.getElementById(' | ||
+ | scene.rotation.y = document.getElementById(' | ||
+ | scene.rotation.z = document.getElementById(' | ||
+ | |||
+ | renderer.render(scene, | ||
+ | } | ||
+ | |||
+ | function updateCamera() { | ||
+ | camera.position.set( | ||
+ | parseFloat(document.getElementById(' | ||
+ | parseFloat(document.getElementById(' | ||
+ | parseFloat(document.getElementById(' | ||
+ | ); | ||
+ | |||
+ | camera.rotation.set( | ||
+ | parseFloat(document.getElementById(' | ||
+ | parseFloat(document.getElementById(' | ||
+ | parseFloat(document.getElementById(' | ||
+ | ); | ||
+ | |||
+ | renderer.render(scene, | ||
+ | } | ||
+ | |||
+ | window.addEventListener(' | ||
+ | renderer.setSize(window.innerWidth, | ||
+ | camera.aspect = window.innerWidth / window.innerHeight; | ||
+ | camera.updateProjectionMatrix(); | ||
+ | }); | ||
+ | |||
+ | document.getElementById(' | ||
+ | scene.rotation.x = this.value * Math.PI / 180; | ||
+ | document.getElementById(' | ||
+ | }); | ||
+ | |||
+ | document.getElementById(' | ||
+ | scene.rotation.y = this.value * Math.PI / 180; | ||
+ | document.getElementById(' | ||
+ | }); | ||
+ | |||
+ | document.getElementById(' | ||
+ | scene.rotation.z = this.value * Math.PI / 180; | ||
+ | document.getElementById(' | ||
+ | }); | ||
+ | |||
+ | document.getElementById(' | ||
+ | const value = parseFloat(this.value); | ||
+ | scene.rotation.x = value * Math.PI / 180; | ||
+ | document.getElementById(' | ||
+ | }); | ||
+ | |||
+ | document.getElementById(' | ||
+ | const value = parseFloat(this.value); | ||
+ | scene.rotation.y = value * Math.PI / 180; | ||
+ | document.getElementById(' | ||
+ | }); | ||
+ | |||
+ | document.getElementById(' | ||
+ | const value = parseFloat(this.value); | ||
+ | scene.rotation.z = value * Math.PI / 180; | ||
+ | document.getElementById(' | ||
+ | }); | ||
+ | |||
+ | document.getElementById(' | ||
+ | document.getElementById(' | ||
+ | document.getElementById(' | ||
+ | document.getElementById(' | ||
+ | document.getElementById(' | ||
+ | document.getElementById(' | ||
+ | |||
+ | animate(); | ||
+ | updateVectors(); | ||
+ | updateCamera(); | ||
+ | |||
+ | //for(var i = 0; i<5; i++) zoomOut(); | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
=====Links===== | =====Links===== |