{"id":3569,"date":"2026-03-06T15:45:40","date_gmt":"2026-03-06T13:45:40","guid":{"rendered":"https:\/\/wordpress.wvs-berlin.de\/?p=3569"},"modified":"2026-03-06T17:17:42","modified_gmt":"2026-03-06T15:17:42","slug":"6-3-2026","status":"publish","type":"post","link":"https:\/\/wordpress.wvs-berlin.de\/?p=3569","title":{"rendered":"6.3.2026"},"content":{"rendered":"\n<p>Heute ist eine weitere Person der SuS dazu gekommen. Die Forscher:innen-AG hat offenbar auch Zuwachs bekommen. Wir haben ein Auto-Loop-Batch-Script angeschaut. <\/p>\n\n\n\n<p>Notizen: <a href=\"https:\/\/fobizz.com\/de\/\">https:\/\/fobizz.com\/de\/<\/a><\/p>\n\n\n\n<p>N\u00e4chste Mal normal. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"787\" height=\"824\" src=\"https:\/\/wordpress.wvs-berlin.de\/wp-content\/uploads\/image-3.png\" alt=\"\" class=\"wp-image-3573\" srcset=\"https:\/\/wordpress.wvs-berlin.de\/wp-content\/uploads\/image-3.png 787w, https:\/\/wordpress.wvs-berlin.de\/wp-content\/uploads\/image-3-287x300.png 287w, https:\/\/wordpress.wvs-berlin.de\/wp-content\/uploads\/image-3-768x804.png 768w\" sizes=\"auto, (max-width: 787px) 100vw, 787px\" \/><\/figure>\n\n\n\n<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>12 \u00d7 K\u2081\u2082 \u2014 3D<\/title>\n<style>\n  * { margin: 0; padding: 0; box-sizing: border-box; }\n  body { background: #000; overflow: hidden; }\n  canvas { display: block; }\n  #hint {\n    position: fixed;\n    bottom: 16px;\n    left: 50%;\n    transform: translateX(-50%);\n    color: rgba(255,255,255,0.2);\n    font: 12px monospace;\n    letter-spacing: 0.1em;\n    pointer-events: none;\n    transition: opacity 2s;\n  }\n<\/style>\n<\/head>\n<body>\n<div id=\"hint\">ziehen zum drehen \u00b7 scrollen zum zoomen<\/div>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/three.js\/r128\/three.min.js\"><\/script>\n<script>\n(() => {\n  \/\/ === Config ===\n  const NC = 12;\n  const NP = 12;\n  const BIG_R = 5.0;\n  const SMALL_R = 1.1;\n\n  \/\/ === Setup ===\n  const scene = new THREE.Scene();\n  const camera = new THREE.PerspectiveCamera(55, window.innerWidth \/ window.innerHeight, 0.1, 100);\n  camera.position.set(0, 6, 14);\n  camera.lookAt(0, 0, 0);\n\n  const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false });\n  renderer.setSize(window.innerWidth, window.innerHeight);\n  renderer.setPixelRatio(window.devicePixelRatio);\n  renderer.setClearColor(0x000000);\n  document.body.appendChild(renderer.domElement);\n\n  \/\/ === Distribute NC points on sphere (Fibonacci) ===\n  function fibSphere(n, radius) {\n    const pts = [];\n    const goldenAngle = Math.PI * (3 - Math.sqrt(5));\n    for (let i = 0; i < n; i++) {\n      const y = 1 - (i \/ (n - 1)) * 2;\n      const r = Math.sqrt(1 - y * y);\n      const theta = goldenAngle * i;\n      pts.push(new THREE.Vector3(\n        r * Math.cos(theta) * radius,\n        y * radius,\n        r * Math.sin(theta) * radius\n      ));\n    }\n    return pts;\n  }\n\n  \/\/ Cluster centers on big sphere\n  const centers = fibSphere(NC, BIG_R);\n\n  \/\/ Hues\n  const hues = [];\n  for (let i = 0; i < NC; i++) hues.push((i * 30) % 360);\n\n  function hslToRGB(h, s, l) {\n    s \/= 100; l \/= 100;\n    const k = n => (n + h \/ 30) % 12;\n    const a = s * Math.min(l, 1 - l);\n    const f = n => l - a * Math.max(-1, Math.min(k(n) - 3, 9 - k(n), 1));\n    return new THREE.Color(f(0), f(4), f(8));\n  }\n\n  \/\/ === Build geometry ===\n  const clusters = [];\n\n  for (let ci = 0; ci < NC; ci++) {\n    const center = centers[ci];\n    const h = hues[ci];\n\n    \/\/ Local points on small sphere around center\n    const localPts = fibSphere(NP, SMALL_R);\n    const worldPts = localPts.map(p => p.clone().add(center));\n\n    clusters.push({ center, points: worldPts, hue: h });\n  }\n\n  \/\/ === Create line materials & geometries ===\n  const macroGroup = new THREE.Group();\n  const intraGroup = new THREE.Group();\n  const dotsGroup = new THREE.Group();\n\n  \/\/ --- Macro lines (cluster center to center) ---\n  for (let i = 0; i < NC; i++) {\n    for (let j = i + 1; j < NC; j++) {\n      const mixH = (hues[i] + hues[j]) \/ 2;\n      const color = hslToRGB(mixH, 45, 55);\n\n      const geom = new THREE.BufferGeometry().setFromPoints([\n        clusters[i].center, clusters[j].center\n      ]);\n      const mat = new THREE.LineBasicMaterial({\n        color: color,\n        transparent: true,\n        opacity: 0.2,\n        linewidth: 1\n      });\n      macroGroup.add(new THREE.Line(geom, mat));\n    }\n  }\n\n  \/\/ --- Intra-cluster lines ---\n  for (let ci = 0; ci < NC; ci++) {\n    const pts = clusters[ci].points;\n    const color = hslToRGB(hues[ci], 65, 60);\n\n    \/\/ Batch all intra lines into one geometry for performance\n    const positions = [];\n    for (let i = 0; i < NP; i++) {\n      for (let j = i + 1; j < NP; j++) {\n        positions.push(pts[i].x, pts[i].y, pts[i].z);\n        positions.push(pts[j].x, pts[j].y, pts[j].z);\n      }\n    }\n    const geom = new THREE.BufferGeometry();\n    geom.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n    const mat = new THREE.LineBasicMaterial({\n      color: color,\n      transparent: true,\n      opacity: 0.45\n    });\n    intraGroup.add(new THREE.LineSegments(geom, mat));\n  }\n\n  \/\/ --- Dots as small spheres ---\n  \/\/ Center dots (bigger)\n  for (let ci = 0; ci < NC; ci++) {\n    const color = hslToRGB(hues[ci], 60, 80);\n    const geo = new THREE.SphereGeometry(0.1, 12, 12);\n    const mat = new THREE.MeshBasicMaterial({ color });\n    const mesh = new THREE.Mesh(geo, mat);\n    mesh.position.copy(clusters[ci].center);\n    dotsGroup.add(mesh);\n  }\n\n  \/\/ Small point dots\n  for (let ci = 0; ci < NC; ci++) {\n    const color = hslToRGB(hues[ci], 70, 85);\n    const geo = new THREE.SphereGeometry(0.05, 8, 8);\n    const mat = new THREE.MeshBasicMaterial({ color });\n\n    for (let i = 0; i < NP; i++) {\n      const mesh = new THREE.Mesh(geo, mat);\n      mesh.position.copy(clusters[ci].points[i]);\n      dotsGroup.add(mesh);\n    }\n  }\n\n  \/\/ --- Glow sprites for cluster centers ---\n  const glowCanvas = document.createElement('canvas');\n  glowCanvas.width = 64;\n  glowCanvas.height = 64;\n  const gctx = glowCanvas.getContext('2d');\n  const grad = gctx.createRadialGradient(32, 32, 0, 32, 32, 32);\n  grad.addColorStop(0, 'rgba(255,255,255,0.6)');\n  grad.addColorStop(0.3, 'rgba(255,255,255,0.15)');\n  grad.addColorStop(1, 'rgba(255,255,255,0)');\n  gctx.fillStyle = grad;\n  gctx.fillRect(0, 0, 64, 64);\n  const glowTex = new THREE.CanvasTexture(glowCanvas);\n\n  for (let ci = 0; ci < NC; ci++) {\n    const color = hslToRGB(hues[ci], 70, 65);\n    const spriteMat = new THREE.SpriteMaterial({\n      map: glowTex,\n      color: color,\n      transparent: true,\n      opacity: 0.4,\n      blending: THREE.AdditiveBlending,\n      depthWrite: false\n    });\n    const sprite = new THREE.Sprite(spriteMat);\n    sprite.position.copy(clusters[ci].center);\n    sprite.scale.set(1.8, 1.8, 1);\n    dotsGroup.add(sprite);\n  }\n\n  scene.add(macroGroup);\n  scene.add(intraGroup);\n  scene.add(dotsGroup);\n\n  \/\/ === Simple orbit controls (no import needed) ===\n  let isDragging = false;\n  let prevMouse = { x: 0, y: 0 };\n  let rotY = 0, rotX = 0.3;\n  let targetRotY = 0, targetRotX = 0.3;\n  let autoRotate = true;\n  let dist = 14, targetDist = 14;\n\n  renderer.domElement.addEventListener('mousedown', e => {\n    isDragging = true;\n    prevMouse = { x: e.clientX, y: e.clientY };\n    autoRotate = false;\n    document.getElementById('hint').style.opacity = '0';\n  });\n  renderer.domElement.addEventListener('mousemove', e => {\n    if (!isDragging) return;\n    const dx = e.clientX - prevMouse.x;\n    const dy = e.clientY - prevMouse.y;\n    targetRotY += dx * 0.005;\n    targetRotX += dy * 0.005;\n    targetRotX = Math.max(-Math.PI \/ 2, Math.min(Math.PI \/ 2, targetRotX));\n    prevMouse = { x: e.clientX, y: e.clientY };\n  });\n  renderer.domElement.addEventListener('mouseup', () => isDragging = false);\n  renderer.domElement.addEventListener('mouseleave', () => isDragging = false);\n\n  \/\/ Touch\n  renderer.domElement.addEventListener('touchstart', e => {\n    isDragging = true;\n    prevMouse = { x: e.touches[0].clientX, y: e.touches[0].clientY };\n    autoRotate = false;\n    document.getElementById('hint').style.opacity = '0';\n  });\n  renderer.domElement.addEventListener('touchmove', e => {\n    if (!isDragging) return;\n    e.preventDefault();\n    const dx = e.touches[0].clientX - prevMouse.x;\n    const dy = e.touches[0].clientY - prevMouse.y;\n    targetRotY += dx * 0.005;\n    targetRotX += dy * 0.005;\n    targetRotX = Math.max(-Math.PI \/ 2, Math.min(Math.PI \/ 2, targetRotX));\n    prevMouse = { x: e.touches[0].clientX, y: e.touches[0].clientY };\n  }, { passive: false });\n  renderer.domElement.addEventListener('touchend', () => isDragging = false);\n\n  \/\/ Zoom\n  renderer.domElement.addEventListener('wheel', e => {\n    targetDist += e.deltaY * 0.01;\n    targetDist = Math.max(5, Math.min(30, targetDist));\n    document.getElementById('hint').style.opacity = '0';\n  });\n\n  \/\/ === Animate ===\n  function animate() {\n    requestAnimationFrame(animate);\n\n    if (autoRotate) targetRotY += 0.003;\n\n    \/\/ Smooth interpolation\n    rotY += (targetRotY - rotY) * 0.08;\n    rotX += (targetRotX - rotX) * 0.08;\n    dist += (targetDist - dist) * 0.08;\n\n    camera.position.set(\n      dist * Math.cos(rotX) * Math.sin(rotY),\n      dist * Math.sin(rotX),\n      dist * Math.cos(rotX) * Math.cos(rotY)\n    );\n    camera.lookAt(0, 0, 0);\n\n    renderer.render(scene, camera);\n  }\n\n  animate();\n\n  \/\/ Resize\n  window.addEventListener('resize', () => {\n    camera.aspect = window.innerWidth \/ window.innerHeight;\n    camera.updateProjectionMatrix();\n    renderer.setSize(window.innerWidth, window.innerHeight);\n  });\n})();\n<\/script>\n<\/body>\n<\/html>\n\n\n\n<p>Claude &#8211; Kugeln. <\/p>\n\n\n\n<p>Rotierende Kugeln: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html lang=\"de\">\n&lt;head>\n&lt;meta charset=\"UTF-8\">\n&lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n&lt;title>32 \u00d7 K\u2083\u2082 \u2014 Kreisel&lt;\/title>\n&lt;style>\n  * { margin: 0; padding: 0; box-sizing: border-box; }\n  body { background: #000; overflow: hidden; }\n  canvas { display: block; }\n  #hint {\n    position: fixed; bottom: 16px; left: 50%; transform: translateX(-50%);\n    color: rgba(255,255,255,0.18); font: 11px monospace;\n    letter-spacing: 0.1em; pointer-events: none; transition: opacity 3s;\n  }\n&lt;\/style>\n&lt;\/head>\n&lt;body>\n&lt;div id=\"hint\">ziehen zum drehen \u00b7 scrollen zum zoomen&lt;\/div>\n&lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/three.js\/r128\/three.min.js\">&lt;\/script>\n&lt;script>\n(() => {\n  const NC = 32;\n  const NP = 32;\n  const BIG_R = 8.0;\n  const SMALL_R = 1.1;\n\n  const scene = new THREE.Scene();\n  const camera = new THREE.PerspectiveCamera(50, window.innerWidth \/ window.innerHeight, 0.1, 300);\n  const renderer = new THREE.WebGLRenderer({ antialias: true });\n  renderer.setSize(window.innerWidth, window.innerHeight);\n  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n  renderer.setClearColor(0x000000);\n  document.body.appendChild(renderer.domElement);\n\n  function fibSphere(n, radius) {\n    const pts = &#91;];\n    const golden = Math.PI * (3 - Math.sqrt(5));\n    for (let i = 0; i &lt; n; i++) {\n      const y = 1 - (i \/ (n - 1)) * 2;\n      const r = Math.sqrt(1 - y * y);\n      const theta = golden * i;\n      pts.push(new THREE.Vector3(r * Math.cos(theta) * radius, y * radius, r * Math.sin(theta) * radius));\n    }\n    return pts;\n  }\n\n  function hslToRGB(h, s, l) {\n    s \/= 100; l \/= 100;\n    const k = n => (n + h \/ 30) % 12;\n    const a = s * Math.min(l, 1 - l);\n    const f = n => l - a * Math.max(-1, Math.min(k(n) - 3, 9 - k(n), 1));\n    return new THREE.Color(f(0), f(4), f(8));\n  }\n\n  \/\/ Gyro for meta sphere: very slow\n  function createMetaGyro() {\n    return {\n      getAxis(t) {\n        const tilt = 0.25 + 0.15 * Math.sin(t * 0.004) + 0.08 * Math.sin(t * 0.0025);\n        const prec = t * 0.002 + 0.2 * Math.sin(t * 0.0013);\n        return new THREE.Vector3(\n          Math.sin(tilt) * Math.cos(prec),\n          Math.cos(tilt),\n          Math.sin(tilt) * Math.sin(prec)\n        ).normalize();\n      },\n      getSpeed(t) {\n        return 0.00025 * (1.0 + 0.3 * Math.sin(t * 0.006));\n      }\n    };\n  }\n\n  \/\/ Gyro for small spheres: clearly visible rotation, each unique\n  function createClusterGyro(seed) {\n    const s = seed;\n    \/\/ Each small sphere gets a distinct base speed\n    const base = 0.0015 + (s % 13) * 0.0002;\n    return {\n      getAxis(t) {\n        const tilt = 0.3 + 0.2 * Math.sin(t * (0.006 + s * 0.001) + s * 1.7)\n                         + 0.1 * Math.sin(t * (0.004 + s * 0.0007) + s * 0.9);\n        const prec = t * (0.004 + s * 0.0005) + 0.3 * Math.sin(t * (0.003 + s * 0.0008) + s * 2.3);\n        return new THREE.Vector3(\n          Math.sin(tilt) * Math.cos(prec),\n          Math.cos(tilt),\n          Math.sin(tilt) * Math.sin(prec)\n        ).normalize();\n      },\n      getSpeed(t) {\n        return base * (1.0 + 0.25 * Math.sin(t * (0.008 + s * 0.001) + s * 0.7));\n      }\n    };\n  }\n\n  const centers = fibSphere(NC, BIG_R);\n  const hues = &#91;];\n  for (let i = 0; i &lt; NC; i++) hues.push((i * 360 \/ NC) % 360);\n\n  const gc = document.createElement('canvas');\n  gc.width = 128; gc.height = 128;\n  const gx = gc.getContext('2d');\n  const gr = gx.createRadialGradient(64, 64, 0, 64, 64, 64);\n  gr.addColorStop(0, 'rgba(255,255,255,0.9)');\n  gr.addColorStop(0.15, 'rgba(255,255,255,0.3)');\n  gr.addColorStop(0.4, 'rgba(255,255,255,0.05)');\n  gr.addColorStop(1, 'rgba(255,255,255,0)');\n  gx.fillStyle = gr;\n  gx.fillRect(0, 0, 128, 128);\n  const glowTex = new THREE.CanvasTexture(gc);\n\n  \/\/ === Build clusters \u2014 each is a pivot group with a spinning inner group ===\n  \/\/ pivot sits at center position (doesn't rotate)\n  \/\/ inner group sits at (0,0,0) inside pivot and rotates\n  const clusterPivots = &#91;];\n  const clusterInners = &#91;];\n  const clusterGyros = &#91;];\n\n  for (let ci = 0; ci &lt; NC; ci++) {\n    const pivot = new THREE.Group();\n    pivot.position.copy(centers&#91;ci]);\n\n    const inner = new THREE.Group();\n    pivot.add(inner);\n\n    const h = hues&#91;ci];\n    const localPts = fibSphere(NP, SMALL_R);\n\n    \/\/ Shell on inner (rotates with it)\n    const shellGeo = new THREE.SphereGeometry(SMALL_R, 24, 18);\n    const color = hslToRGB(h, 45, 32);\n    inner.add(new THREE.Mesh(shellGeo, new THREE.MeshBasicMaterial({\n      color, transparent: true, opacity: 0.05, side: THREE.DoubleSide, depthWrite: false\n    })));\n    inner.add(new THREE.Mesh(shellGeo, new THREE.MeshBasicMaterial({\n      color, wireframe: true, transparent: true, opacity: 0.025\n    })));\n\n    \/\/ Intra lines\n    const pos = &#91;];\n    for (let i = 0; i &lt; NP; i++)\n      for (let j = i + 1; j &lt; NP; j++) {\n        pos.push(localPts&#91;i].x, localPts&#91;i].y, localPts&#91;i].z);\n        pos.push(localPts&#91;j].x, localPts&#91;j].y, localPts&#91;j].z);\n      }\n    const lg = new THREE.BufferGeometry();\n    lg.setAttribute('position', new THREE.Float32BufferAttribute(pos, 3));\n    inner.add(new THREE.LineSegments(lg, new THREE.LineBasicMaterial({\n      color: hslToRGB(h, 55, 52), transparent: true, opacity: 0.25\n    })));\n\n    \/\/ Dots\n    const dotGeo = new THREE.SphereGeometry(0.035, 4, 4);\n    const dotMat = new THREE.MeshBasicMaterial({ color: hslToRGB(h, 60, 82) });\n    for (let i = 0; i &lt; NP; i++) {\n      const m = new THREE.Mesh(dotGeo, dotMat);\n      m.position.copy(localPts&#91;i]);\n      inner.add(m);\n    }\n    for (let i = 0; i &lt; NP; i += 2) {\n      const s = new THREE.Sprite(new THREE.SpriteMaterial({\n        map: glowTex, color: hslToRGB(h, 60, 58),\n        transparent: true, opacity: 0.12,\n        blending: THREE.AdditiveBlending, depthWrite: false\n      }));\n      s.position.copy(localPts&#91;i]);\n      s.scale.set(0.4, 0.4, 1);\n      inner.add(s);\n    }\n\n    \/\/ Center dot (on pivot, doesn't rotate \u2014 stays at center)\n    pivot.add(new THREE.Mesh(\n      new THREE.SphereGeometry(0.14, 10, 10),\n      new THREE.MeshBasicMaterial({ color: hslToRGB(h, 55, 80) })\n    ));\n    const cg = new THREE.Sprite(new THREE.SpriteMaterial({\n      map: glowTex, color: hslToRGB(h, 60, 55),\n      transparent: true, opacity: 0.5,\n      blending: THREE.AdditiveBlending, depthWrite: false\n    }));\n    cg.scale.set(1.8, 1.8, 1);\n    pivot.add(cg);\n\n    clusterPivots.push(pivot);\n    clusterInners.push(inner);\n    clusterGyros.push(createClusterGyro(ci + 1));\n  }\n\n  \/\/ === Meta group ===\n  const metaGroup = new THREE.Group();\n\n  const metaGeo = new THREE.SphereGeometry(BIG_R, 48, 36);\n  metaGroup.add(new THREE.Mesh(metaGeo, new THREE.MeshBasicMaterial({\n    color: new THREE.Color(0.15, 0.18, 0.25),\n    transparent: true, opacity: 0.04, side: THREE.DoubleSide, depthWrite: false\n  })));\n  metaGroup.add(new THREE.Mesh(metaGeo, new THREE.MeshBasicMaterial({\n    color: new THREE.Color(0.3, 0.35, 0.45),\n    wireframe: true, transparent: true, opacity: 0.03, depthWrite: false\n  })));\n  for (let lat = -2; lat &lt;= 2; lat++) {\n    const y = (lat \/ 3) * BIG_R;\n    const ringR = Math.sqrt(BIG_R * BIG_R - y * y);\n    const curve = new THREE.EllipseCurve(0, 0, ringR, ringR, 0, Math.PI * 2, false, 0);\n    const pts2d = curve.getPoints(80);\n    const pts3d = pts2d.map(p => new THREE.Vector3(p.x, y, p.y));\n    metaGroup.add(new THREE.LineLoop(\n      new THREE.BufferGeometry().setFromPoints(pts3d),\n      new THREE.LineBasicMaterial({ color: new THREE.Color(0.4, 0.45, 0.55), transparent: true, opacity: 0.06 })\n    ));\n  }\n\n  function makeTube(a, b, radius, color, opacity) {\n    const dir = new THREE.Vector3().subVectors(b, a);\n    const len = dir.length();\n    const mid = new THREE.Vector3().addVectors(a, b).multiplyScalar(0.5);\n    const geo = new THREE.CylinderGeometry(radius, radius, len, 4, 1);\n    const mat = new THREE.MeshBasicMaterial({ color, transparent: true, opacity, depthWrite: false });\n    const mesh = new THREE.Mesh(geo, mat);\n    mesh.position.copy(mid);\n    mesh.lookAt(b);\n    mesh.rotateX(Math.PI \/ 2);\n    return mesh;\n  }\n  for (let i = 0; i &lt; NC; i++) {\n    for (let j = i + 1; j &lt; NC; j++) {\n      const mixH = (hues&#91;i] + hues&#91;j]) \/ 2;\n      metaGroup.add(makeTube(centers&#91;i], centers&#91;j], 0.06, hslToRGB(mixH, 45, 45), 0.07));\n      metaGroup.add(makeTube(centers&#91;i], centers&#91;j], 0.025, hslToRGB(mixH, 50, 55), 0.3));\n    }\n  }\n\n  clusterPivots.forEach(p => metaGroup.add(p));\n\n  \/\/ Meta center\n  const metaCenterMat = new THREE.MeshBasicMaterial({\n    color: new THREE.Color(1, 1, 1), transparent: true, opacity: 0.6\n  });\n  metaGroup.add(new THREE.Mesh(new THREE.SphereGeometry(1.0, 24, 24), metaCenterMat));\n  const metaGlowMat = new THREE.SpriteMaterial({\n    map: glowTex, color: new THREE.Color(1, 1, 1),\n    transparent: true, opacity: 0.6,\n    blending: THREE.AdditiveBlending, depthWrite: false\n  });\n  const metaGlowSprite = new THREE.Sprite(metaGlowMat);\n  metaGlowSprite.scale.set(14, 14, 1);\n  metaGroup.add(metaGlowSprite);\n  const metaGlow2Mat = new THREE.SpriteMaterial({\n    map: glowTex, color: new THREE.Color(1, 1, 1),\n    transparent: true, opacity: 0.2,\n    blending: THREE.AdditiveBlending, depthWrite: false\n  });\n  const metaGlow2Sprite = new THREE.Sprite(metaGlow2Mat);\n  metaGlow2Sprite.scale.set(22, 22, 1);\n  metaGroup.add(metaGlow2Sprite);\n\n  scene.add(metaGroup);\n\n  const metaGyro = createMetaGyro();\n\n  \/\/ === Camera ===\n  let isDrag = false, prevM = { x: 0, y: 0 };\n  let camRotY = 0, camRotX = 0.3, tCamRotY = 0, tCamRotX = 0.3;\n  let dist = 26, tDist = 26;\n  const el = renderer.domElement;\n\n  el.addEventListener('mousedown', e => { isDrag = true; prevM = { x: e.clientX, y: e.clientY }; fadeHint(); });\n  el.addEventListener('mousemove', e => {\n    if (!isDrag) return;\n    tCamRotY += (e.clientX - prevM.x) * 0.004;\n    tCamRotX += (e.clientY - prevM.y) * 0.004;\n    tCamRotX = Math.max(-1.5, Math.min(1.5, tCamRotX));\n    prevM = { x: e.clientX, y: e.clientY };\n  });\n  el.addEventListener('mouseup', () => isDrag = false);\n  el.addEventListener('mouseleave', () => isDrag = false);\n  el.addEventListener('touchstart', e => { isDrag = true; prevM = { x: e.touches&#91;0].clientX, y: e.touches&#91;0].clientY }; fadeHint(); });\n  el.addEventListener('touchmove', e => {\n    if (!isDrag) return; e.preventDefault();\n    tCamRotY += (e.touches&#91;0].clientX - prevM.x) * 0.004;\n    tCamRotX += (e.touches&#91;0].clientY - prevM.y) * 0.004;\n    tCamRotX = Math.max(-1.5, Math.min(1.5, tCamRotX));\n    prevM = { x: e.touches&#91;0].clientX, y: e.touches&#91;0].clientY };\n  }, { passive: false });\n  el.addEventListener('touchend', () => isDrag = false);\n  el.addEventListener('wheel', e => { tDist += e.deltaY * 0.02; tDist = Math.max(10, Math.min(60, tDist)); fadeHint(); });\n\n  function fadeHint() { document.getElementById('hint').style.opacity = '0'; }\n\n  let time = 0;\n  const quat = new THREE.Quaternion();\n\n  function animate() {\n    requestAnimationFrame(animate);\n    time += 0.008;\n\n    camRotY += (tCamRotY - camRotY) * 0.06;\n    camRotX += (tCamRotX - camRotX) * 0.06;\n    dist += (tDist - dist) * 0.06;\n    camera.position.set(\n      dist * Math.cos(camRotX) * Math.sin(camRotY),\n      dist * Math.sin(camRotX),\n      dist * Math.cos(camRotX) * Math.cos(camRotY)\n    );\n    camera.lookAt(0, 0, 0);\n\n    \/\/ Meta: very slow gyroscopic rotation\n    const metaAxis = metaGyro.getAxis(time);\n    quat.setFromAxisAngle(metaAxis, metaGyro.getSpeed(time));\n    metaGroup.quaternion.multiply(quat);\n\n    \/\/ Each small sphere: independent visible rotation\n    for (let ci = 0; ci &lt; NC; ci++) {\n      const axis = clusterGyros&#91;ci].getAxis(time);\n      const speed = clusterGyros&#91;ci].getSpeed(time);\n      quat.setFromAxisAngle(axis, speed);\n      clusterInners&#91;ci].quaternion.multiply(quat);\n    }\n\n    \/\/ Iridescent center (slow)\n    const h = (time * 3) % 360;\n    metaCenterMat.color.copy(hslToRGB(h, 50, 70));\n    metaGlowMat.color.copy(hslToRGB(h, 60, 50));\n    metaGlow2Mat.color.copy(hslToRGB((h + 60) % 360, 40, 40));\n\n    renderer.render(scene, camera);\n  }\n  animate();\n\n  window.addEventListener('resize', () => {\n    camera.aspect = window.innerWidth \/ window.innerHeight;\n    camera.updateProjectionMatrix();\n    renderer.setSize(window.innerWidth, window.innerHeight);\n  });\n})();\n&lt;\/script>\n&lt;\/body>\n&lt;\/html><\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Heute ist eine weitere Person der SuS dazu gekommen. Die Forscher:innen-AG hat offenbar auch Zuwachs bekommen. Wir haben ein Auto-Loop-Batch-Script angeschaut. Notizen: https:\/\/fobizz.com\/de\/ N\u00e4chste Mal normal. 12 \u00d7 K\u2081\u2082 \u2014 3D ziehen zum drehen \u00b7 scrollen zum zoomen Claude &#8211; Kugeln. Rotierende Kugeln:<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,3,7],"tags":[],"class_list":["post-3569","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-tagesberichte","category-termine"],"_links":{"self":[{"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=\/wp\/v2\/posts\/3569","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3569"}],"version-history":[{"count":7,"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=\/wp\/v2\/posts\/3569\/revisions"}],"predecessor-version":[{"id":3577,"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=\/wp\/v2\/posts\/3569\/revisions\/3577"}],"wp:attachment":[{"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3569"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3569"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.wvs-berlin.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3569"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}