Mandelbrot mit JSXGraph
Aus Wiki1
(Unterschied zwischen Versionen)
| (Der Versionsvergleich bezieht 39 dazwischenliegende Versionen mit ein.) | |||
| Zeile 1: | Zeile 1: | ||
| - | <jsxgraph box="jxgbox" width=" | + | <jsxgraph box="jxgbox" width="600" height="700"> |
| - | + | ||
| - | + | const board = JXG.JSXGraph.initBoard('jxgbox', { | |
boundingbox: [-2.5, 1.5, 1.5, -1.5], | boundingbox: [-2.5, 1.5, 1.5, -1.5], | ||
| - | axis: | + | axis: false, |
showNavigation: false, | showNavigation: false, | ||
showCopyright: false | showCopyright: false | ||
| Zeile 9: | Zeile 9: | ||
// Slider für Iterationstiefe | // Slider für Iterationstiefe | ||
| - | + | const sliderIter = board.create('slider', [[-2.3, 1.3], [0.5, 1.3], [10, 50, 300]], { | |
name:'Tiefe', | name:'Tiefe', | ||
snapWidth:1 | snapWidth:1 | ||
}); | }); | ||
| + | |||
| + | // Slider für Zoom | ||
| + | const sliderZoom = board.create('slider', [[-2.3, 1.2], [0.5, 1.2], [1, 1, 50]], { | ||
| + | name:'Zoom', | ||
| + | snapWidth:1 | ||
| + | }); | ||
| + | |||
// Canvas ins DOM hängen | // Canvas ins DOM hängen | ||
const div = document.getElementById('jxgbox'); | const div = document.getElementById('jxgbox'); | ||
const canvas = document.createElement('canvas'); | const canvas = document.createElement('canvas'); | ||
| - | canvas.width = | + | canvas.width = 600; |
| - | canvas.height = | + | canvas.height = 600; |
canvas.style.position = 'absolute'; | canvas.style.position = 'absolute'; | ||
canvas.style.left = "0px"; | canvas.style.left = "0px"; | ||
| - | canvas.style.top = " | + | canvas.style.top = "150px"; |
div.appendChild(canvas); | div.appendChild(canvas); | ||
const ctx = canvas.getContext('2d'); | const ctx = canvas.getContext('2d'); | ||
| + | // Mandelbrot-Berechnung | ||
function mandelbrotIter(cx, cy, maxIter) { | function mandelbrotIter(cx, cy, maxIter) { | ||
let x = 0, y = 0, iter = 0; | let x = 0, y = 0, iter = 0; | ||
| Zeile 36: | Zeile 44: | ||
} | } | ||
| - | function drawMandelbrot(maxIter) { | + | // Anfangsbereich |
| - | const | + | let centerX = -0.5; |
| + | let centerY = 0; | ||
| + | let baseWidth = 3.5; | ||
| + | let baseHeight = 3.0; | ||
| + | |||
| + | function drawMandelbrot(maxIter, zoom) { | ||
| + | const spanX = baseWidth / zoom; | ||
| + | const spanY = baseHeight / zoom; | ||
| + | |||
| + | const xMin = centerX - spanX/2; | ||
| + | const xMax = centerX + spanX/2; | ||
| + | const yMin = centerY - spanY/2; | ||
| + | const yMax = centerY + spanY/2; | ||
| + | |||
const img = ctx.createImageData(canvas.width, canvas.height); | const img = ctx.createImageData(canvas.width, canvas.height); | ||
for (let px = 0; px < canvas.width; px++) { | for (let px = 0; px < canvas.width; px++) { | ||
for (let py = 0; py < canvas.height; py++) { | for (let py = 0; py < canvas.height; py++) { | ||
| - | + | const cx = xMin + (px / canvas.width) * (xMax - xMin); | |
| - | const cx = | + | const cy = yMin + (py / canvas.height) * (yMax - yMin); |
| - | const cy = | + | |
const iter = mandelbrotIter(cx, cy, maxIter); | const iter = mandelbrotIter(cx, cy, maxIter); | ||
| Zeile 50: | Zeile 70: | ||
if (iter >= maxIter) { | if (iter >= maxIter) { | ||
| - | img.data[idx] = 0; | + | img.data[idx] = 0; |
| - | img.data[idx+1] = 0; | + | img.data[idx+1] = 0; |
| - | img.data[idx+2] = 0; | + | img.data[idx+2] = 0; |
| - | img.data[idx+3] = 255; | + | img.data[idx+3] = 255; |
} else { | } else { | ||
const c = Math.floor(255 * iter / maxIter); | const c = Math.floor(255 * iter / maxIter); | ||
| - | img.data[idx] = c; | + | img.data[idx] = c; |
| - | img.data[idx+1] = 100; | + | img.data[idx+1] = 100; |
| - | img.data[idx+2] = 255 - c; | + | img.data[idx+2] = 255 - c; |
| - | img.data[idx+3] = 255; | + | img.data[idx+3] = 255; |
} | } | ||
} | } | ||
| Zeile 66: | Zeile 86: | ||
} | } | ||
| - | + | function update() { | |
| - | + | drawMandelbrot(Math.round(sliderIter.Value()), Math.round(sliderZoom.Value())); | |
| - | + | } | |
| + | |||
| + | sliderIter.on('drag', update); | ||
| + | sliderZoom.on('drag', update); | ||
| + | |||
| + | |||
| + | // Panning mit Maus | ||
| + | let isDragging = false; | ||
| + | let lastX, lastY; | ||
| + | |||
| + | canvas.addEventListener('mousedown', e => { | ||
| + | isDragging = true; | ||
| + | lastX = e.offsetX; | ||
| + | lastY = e.offsetY; | ||
}); | }); | ||
| - | + | canvas.addEventListener('mouseup', () => { | |
| + | isDragging = false; | ||
| + | }); | ||
| - | + | canvas.addEventListener('mouseleave', () => { | |
| - | + | isDragging = false; | |
| + | }); | ||
| + | canvas.addEventListener('mousemove', e => { | ||
| + | if (isDragging) { | ||
| + | const dx = e.offsetX - lastX; | ||
| + | const dy = e.offsetY - lastY; | ||
| + | lastX = e.offsetX; | ||
| + | lastY = e.offsetY; | ||
| + | |||
| + | // Verschiebung in komplexer Ebene berechnen | ||
| + | const zoom = Math.round(sliderZoom.Value()); | ||
| + | const spanX = baseWidth / zoom; | ||
| + | const spanY = baseHeight / zoom; | ||
| + | |||
| + | centerX -= dx / canvas.width * spanX; | ||
| + | centerY -= dy / canvas.height * spanY; | ||
| + | |||
| + | update(); | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | // Initial zeichnen | ||
| + | update(); | ||
</jsxgraph> | </jsxgraph> | ||
| + | |||
| + | Mit den Schiebereglern können Iterations-Tiefe und Zoom gesteuert werden. Mit der Maus+linke Maustaste kann der Bildausschnitt verschoben werden. | ||
| + | |||
| + | |||
| + | [[Kategorie:KI-generiert]] | ||
Aktuelle Version vom 14:08, 22. Dez. 2025
Mit den Schiebereglern können Iterations-Tiefe und Zoom gesteuert werden. Mit der Maus+linke Maustaste kann der Bildausschnitt verschoben werden.
