java-topology/tests/workbench/Workbench.java
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

746 lines
30 KiB
Java
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package workbench;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleBindings;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Symmetric Embedding Workbench — Java port of kernel.js + kernel.html.
*
* Renders the Sym² manifold with heat diffusion and friend agents.
* No external dependencies. Compile with the patched javac and run with java.
*
* Compile (from tests/):
* java -m jdk.compiler/com.sun.tools.javac.Main -cp . \
* workbench/Manifold.java workbench/Friend.java workbench/Workbench.java
*
* Run:
* java -cp . workbench.Workbench
*/
public class Workbench {
// ── Palette ───────────────────────────────────────────────────────────────
private static final Color BG_PANEL = new Color(0x0d, 0x0d, 0x16);
private static final Color BG_SCENE = Color.WHITE;
private static final Color FG_TEXT = Color.WHITE;
private static final Color PCB_GOLD = new Color(0xff, 0xd7, 0x00);
private static final Color PCB_GREEN = new Color(0x68, 0xff, 0x9a);
private static final Color BORDER_COL = new Color(0x33, 0x33, 0x33);
private static final Color SEAM_COL = new Color(0xff, 0x32, 0x32);
private static final Color WIRE_COL = new Color(0x00, 0x00, 0x00, 128);
// Friend render colors (matching JS palette)
private static final Color[] FRIEND_COLORS = {
new Color(0x68, 0xff, 0x9a), // G — green
new Color(0xff, 0x32, 0x32), // R — red
new Color(0x00, 0xee, 0xff), // C — cyan
new Color(0xff, 0xd7, 0x00), // Y — gold
new Color(0x94, 0x00, 0xd3) // V — violet
};
// ── State ─────────────────────────────────────────────────────────────────
private final Manifold manifold = new Manifold();
private final List<Friend> friends = new ArrayList<>();
private final List<float[]> seedPoints = new ArrayList<>(); // {x, y}
private float flickerRate = 0.05f;
private float wobbleBase = 2.0f;
private int tick = 0;
private String oracleExpr = "Math.sin(t * 0.05) * 5";
private ScriptEngine scriptEngine;
// ── Swing components ──────────────────────────────────────────────────────
private ViewportPanel viewport;
private DrawOverlay drawOverlay;
private JTextArea pcbSource;
private JTextArea pcbOutput;
private JTextField oracleField;
private JPanel matrixBody;
private JButton friendBtn;
private JButton solveBtn;
private JButton inscribeBtn;
// ── Entry point ───────────────────────────────────────────────────────────
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Workbench().start());
}
private void start() {
// Optional: try to load Nashorn for oracle eval
try {
ScriptEngineManager mgr = new ScriptEngineManager();
scriptEngine = mgr.getEngineByName("javascript");
} catch (Exception e) {
scriptEngine = null;
}
PatchVerifier.Status patch = PatchVerifier.check();
JFrame frame = new JFrame("ARK_ID: 1.0.2.10 // JAVA_PORT" +
(patch.patched() ? " [PATCHED]" : " [UNPATCHED]"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
// Header
JPanel header = new JPanel(new BorderLayout());
header.setBackground(BG_PANEL);
header.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, BORDER_COL));
header.setPreferredSize(new Dimension(0, 50));
JLabel title = monoLabel("ARK_ID: 1.0.2.10 // JAVA_PORT", 9, PCB_GOLD);
title.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0));
header.add(title, BorderLayout.WEST);
frame.add(header, BorderLayout.NORTH);
// Main area
JPanel main = new JPanel(new BorderLayout());
viewport = new ViewportPanel();
viewport.setBackground(BG_SCENE);
// Draw overlay (200×200, positioned top-left of viewport area)
JLayeredPane layered = new JLayeredPane();
layered.setLayout(null);
viewport.setBounds(0, 0, 1000, 800); // will be updated on resize
drawOverlay = new DrawOverlay();
drawOverlay.setBounds(10, 10, 200, 200);
layered.add(viewport, JLayeredPane.DEFAULT_LAYER);
layered.add(drawOverlay, JLayeredPane.PALETTE_LAYER);
layered.addComponentListener(new ComponentAdapter() {
@Override public void componentResized(ComponentEvent e) {
Dimension d = layered.getSize();
viewport.setBounds(0, 0, d.width, d.height);
drawOverlay.setBounds(10, 10, 200, 200);
}
});
main.add(layered, BorderLayout.CENTER);
main.add(buildSidebar(), BorderLayout.EAST);
frame.add(main, BorderLayout.CENTER);
frame.setSize(1200, 800);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// Startup banner in PCB output
pcbLog("JAVA: " + System.getProperty("java.version"));
pcbLog("PATCH: " + patch);
pcbLog(scriptEngine != null ? "ORACLE: js engine ready" : "ORACLE: fallback sin(t*0.05)*5");
// Kick off render loop
Timer timer = new Timer(16, e -> tick());
timer.start();
}
// ── Tick (one frame) ──────────────────────────────────────────────────────
private void tick() {
tick++;
if (manifold.built) {
manifold.diffuseHeat();
applyOracle();
for (Friend f : friends) f.compute();
}
if (tick % 20 == 0) updateMatrix();
viewport.repaint();
}
private void applyOracle() {
String expr = oracleField != null ? oracleField.getText().trim() : oracleExpr;
if (expr.isEmpty()) expr = "1";
Random rng = viewport.rng;
float wobble = wobbleBase;
for (int i = 0; i < manifold.vertexCount; i++) {
float ox = manifold.originalPositions[i*3];
float oy = manifold.originalPositions[i*3+1];
float oz = manifold.originalPositions[i*3+2];
float cx = ox, cy = oy;
float d = (float)Math.sqrt(cx*cx + cy*cy) * 0.001f;
float t = tick;
float h = manifold.heat[i];
double w = evalOracle(expr, t, d, i, h);
manifold.positions[i*3] = ox + (rng.nextFloat() - 0.5f) * wobble;
manifold.positions[i*3 + 1] = oy + (rng.nextFloat() - 0.5f) * wobble;
manifold.positions[i*3 + 2] = oz + h * (float)w;
}
// also update seam positions
for (int u = 0; u < Manifold.M; u++) {
int base = (u * Manifold.M + u) * 3;
manifold.seamPositions[u*3] = manifold.positions[base];
manifold.seamPositions[u*3 + 1] = manifold.positions[base + 1];
manifold.seamPositions[u*3 + 2] = manifold.positions[base + 2];
}
}
private double evalOracle(String expr, float t, float d, int i, float heat) {
if (scriptEngine != null) {
try {
SimpleBindings b = new SimpleBindings();
b.put("t", (double)t);
b.put("d", (double)d);
b.put("i", (double)i);
b.put("heat", (double)heat);
Object result = scriptEngine.eval(expr, b);
if (result instanceof Number) return ((Number)result).doubleValue();
} catch (Exception e) { /* fall through */ }
}
// Built-in fallback: sin(t*0.05)*5
return Math.sin(t * 0.05) * 5.0;
}
// ── PCB Console ───────────────────────────────────────────────────────────
private void pcbRun(String input) {
pcbLog("PURGING_DRAWPAD...");
drawOverlay.clear();
seedPoints.clear();
input = input.trim();
if (input.equals("sys.verify")) {
PatchVerifier.Status s = PatchVerifier.check();
pcbLog("PATCH_STATUS: " + s);
return;
}
if (input.startsWith("sys.connect")) {
pcbLog("FRONTIER: Liminal channel open. Speak. (Java port — no API)");
return;
}
// Modulate flicker/wobble from input hash
int sum = 0;
for (char c : input.toCharArray()) sum += c;
flickerRate = (sum % 127) / 1000f + 0.02f;
wobbleBase = (input.isEmpty() ? 1f : (float)sum / input.length()) / 32f;
if (input.equals("E>.<3")) {
injectHeart();
} else if (input.startsWith("manifold.(")) {
java.util.regex.Matcher m = java.util.regex.Pattern
.compile("manifold\\.\\(\\[(.*)\\]\\)").matcher(input);
if (m.find()) {
String[] parts = m.group(1).split(",");
float[] coords = new float[parts.length];
for (int i = 0; i < parts.length; i++) {
try { coords[i] = Float.parseFloat(parts[i].trim()); }
catch (NumberFormatException e) { coords[i] = 0; }
}
injectCoords(coords);
}
} else {
interpretASCII(input);
}
}
private void injectCoords(float[] coords) {
for (int i = 0; i + 1 < coords.length; i += 2) {
float x = coords[i], y = coords[i+1];
seedPoints.add(new float[]{x, y});
drawOverlay.addDot(x, y);
}
buildManifoldFromSeeds();
pcbLog("MANIFOLD: " + seedPoints.size() + " seeds injected");
}
private void interpretASCII(String str) {
float[] coords = new float[str.length() * 2];
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i);
coords[i*2] = 100 + (float)Math.cos(i * 0.4) * val * 0.7f;
coords[i*2 + 1] = 100 + (float)Math.sin(i * 0.4) * val * 0.7f;
}
injectCoords(coords);
}
private void injectHeart() {
List<float[]> pts = new ArrayList<>();
for (double t = 0; t < Math.PI * 2; t += 0.15) {
float x = (float)(16 * Math.pow(Math.sin(t), 3) * 4 + 100);
float y = (float)(-(13*Math.cos(t) - 5*Math.cos(2*t) - 2*Math.cos(3*t) - Math.cos(4*t)) * 4 + 100);
pts.add(new float[]{x, y});
}
float[] coords = new float[pts.size() * 2];
for (int i = 0; i < pts.size(); i++) {
coords[i*2] = pts.get(i)[0];
coords[i*2 + 1] = pts.get(i)[1];
}
injectCoords(coords);
}
private void buildManifoldFromSeeds() {
int n = seedPoints.size();
float[] sx = new float[n], sy = new float[n];
for (int i = 0; i < n; i++) { sx[i] = seedPoints.get(i)[0]; sy[i] = seedPoints.get(i)[1]; }
manifold.build(sx, sy, n);
// relocate existing friends
for (Friend f : friends) f.relocate();
if (friendBtn != null) friendBtn.setEnabled(true);
// reset viewport scale so it re-fits on next draw
viewport.resetScale();
pcbLog("MANIFOLD: built " + manifold.vertexCount + " vertices");
}
private void pcbLog(String msg) {
if (pcbOutput == null) return;
SwingUtilities.invokeLater(() -> {
pcbOutput.append("\n> " + msg);
pcbOutput.setCaretPosition(pcbOutput.getDocument().getLength());
});
}
private void deployFriends() {
if (!manifold.built) return;
for (int i = 0; i < 5; i++) {
Friend f = new Friend(i, manifold);
int idx = i;
f.onRespawn = () -> pcbLog("AGENT_" + Friend.IDS[idx] + ": RESPAWN at v" + f.vIdx);
f.onBloom = () -> pcbLog("AGENT_" + Friend.IDS[idx] + ": AUTO_MACRO: manifold.patch()");
friends.add(f);
}
if (friendBtn != null) friendBtn.setEnabled(false);
}
private void updateMatrix() {
if (matrixBody == null) return;
SwingUtilities.invokeLater(() -> {
matrixBody.removeAll();
for (Friend f : friends) {
JPanel row = new JPanel(new GridLayout(1, 5, 2, 0));
row.setBackground(BG_PANEL);
row.add(monoLabel(f.id, 8, FRIEND_COLORS[f.idx]));
row.add(monoLabel(String.format("%.0f", f.life), 8, PCB_GREEN));
row.add(monoLabel(String.format("%.1f", f.sap), 8, PCB_GREEN));
row.add(monoLabel(String.valueOf(f.blooms), 8, PCB_GREEN));
row.add(monoLabel("AUTO", 8, PCB_GREEN));
matrixBody.add(row);
}
matrixBody.revalidate();
matrixBody.repaint();
});
}
// ── Sidebar ───────────────────────────────────────────────────────────────
private JPanel buildSidebar() {
JPanel sidebar = new JPanel();
sidebar.setBackground(BG_PANEL);
sidebar.setPreferredSize(new Dimension(420, 0));
sidebar.setLayout(new BoxLayout(sidebar, BoxLayout.Y_AXIS));
sidebar.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, BORDER_COL));
sidebar.add(buildPCBModule());
sidebar.add(Box.createVerticalStrut(8));
sidebar.add(buildOracleModule());
sidebar.add(Box.createVerticalStrut(8));
sidebar.add(buildMatrixModule());
sidebar.add(Box.createVerticalStrut(8));
sidebar.add(buildReifyModule());
sidebar.add(Box.createVerticalGlue());
JButton purgeBtn = new JButton("PURGE_SESSION");
purgeBtn.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 8));
purgeBtn.setBackground(Color.BLACK);
purgeBtn.setForeground(new Color(0xff, 0x32, 0x32));
purgeBtn.setBorder(BorderFactory.createLineBorder(new Color(0xff, 0x32, 0x32)));
purgeBtn.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30));
purgeBtn.addActionListener(e -> purgeSession());
sidebar.add(purgeBtn);
sidebar.add(Box.createVerticalStrut(10));
return sidebar;
}
private JPanel buildPCBModule() {
JPanel p = module("POCKET_CUP_BOX_CONSOLE");
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(PCB_GOLD, 2),
BorderFactory.createEmptyBorder(8, 8, 8, 8)));
pcbSource = new JTextArea(4, 30);
pcbSource.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 9));
pcbSource.setBackground(Color.BLACK);
pcbSource.setForeground(PCB_GOLD);
pcbSource.setCaretColor(PCB_GOLD);
pcbSource.setBorder(BorderFactory.createLineBorder(BORDER_COL));
pcbSource.setText("sys.connect('frontier')");
JButton runBtn = new JButton("RUN_ADMIN_CMD");
runBtn.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 8));
runBtn.setBackground(Color.BLACK);
runBtn.setForeground(PCB_GOLD);
runBtn.setBorder(BorderFactory.createLineBorder(PCB_GOLD));
runBtn.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
runBtn.addActionListener(e -> pcbRun(pcbSource.getText()));
// Enter key in source also runs
pcbSource.addKeyListener(new KeyAdapter() {
@Override public void keyPressed(KeyEvent e) {
if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER)
pcbRun(pcbSource.getText());
}
});
pcbOutput = new JTextArea(3, 30);
pcbOutput.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 8));
pcbOutput.setBackground(new Color(5, 5, 5));
pcbOutput.setForeground(new Color(0x88, 0x88, 0x88));
pcbOutput.setEditable(false);
pcbOutput.setText("PCB_STATUS: IDLE.");
JScrollPane scroll = new JScrollPane(pcbOutput);
scroll.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, PCB_GOLD));
scroll.setMaximumSize(new Dimension(Integer.MAX_VALUE, 60));
p.add(new JScrollPane(pcbSource));
p.add(Box.createVerticalStrut(4));
p.add(runBtn);
p.add(scroll);
return p;
}
private JPanel buildOracleModule() {
JPanel p = module("ORACLE_HEURISTICS");
oracleField = new JTextField(oracleExpr);
oracleField.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 9));
oracleField.setBackground(Color.BLACK);
oracleField.setForeground(PCB_GREEN);
oracleField.setCaretColor(PCB_GREEN);
oracleField.setBorder(BorderFactory.createLineBorder(new Color(0x94, 0x00, 0xd3)));
p.add(oracleField);
return p;
}
private JPanel buildMatrixModule() {
JPanel p = module("AGENT_LABS_MATRIX");
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
// header row
JPanel hdr = new JPanel(new GridLayout(1, 5, 2, 0));
hdr.setBackground(BG_PANEL);
for (String h : new String[]{"ID","LIFE","SAP","BLM","MODE"})
hdr.add(monoLabel(h, 7, new Color(0x44,0x44,0x44)));
p.add(hdr);
matrixBody = new JPanel();
matrixBody.setBackground(BG_PANEL);
matrixBody.setLayout(new BoxLayout(matrixBody, BoxLayout.Y_AXIS));
p.add(matrixBody);
return p;
}
private JPanel buildReifyModule() {
JPanel p = module("REIFY TOOLS");
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
inscribeBtn = sideBtn("INSCRIBE_DRAW_TO_PCB", PCB_GOLD);
inscribeBtn.addActionListener(e -> inscribe());
p.add(inscribeBtn);
p.add(Box.createVerticalStrut(4));
friendBtn = sideBtn("DEPLOY_FRIENDS", Color.WHITE);
friendBtn.setEnabled(false);
friendBtn.addActionListener(e -> deployFriends());
p.add(friendBtn);
p.add(Box.createVerticalStrut(4));
solveBtn = sideBtn("REIFY_MANIFOLD", Color.WHITE);
solveBtn.addActionListener(e -> buildManifoldFromSeeds());
p.add(solveBtn);
return p;
}
private void inscribe() {
if (seedPoints.isEmpty()) return;
int step = Math.max(1, seedPoints.size() / 20);
StringBuilder sb = new StringBuilder("manifold.([");
for (int i = 0; i < seedPoints.size(); i += step) {
if (i > 0) sb.append(',');
sb.append(Math.round(seedPoints.get(i)[0])).append(',')
.append(Math.round(seedPoints.get(i)[1]));
}
sb.append("])");
if (pcbSource != null) pcbSource.setText(sb.toString());
}
private void purgeSession() {
seedPoints.clear();
friends.clear();
manifold.built = false;
drawOverlay.clear();
viewport.resetScale();
if (pcbOutput != null) pcbOutput.setText("PCB_STATUS: IDLE.");
viewport.repaint();
}
// ── Helpers ───────────────────────────────────────────────────────────────
private JPanel module(String title) {
JPanel p = new JPanel(new BorderLayout());
p.setBackground(BG_PANEL);
p.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(BORDER_COL),
BorderFactory.createEmptyBorder(6, 6, 6, 6)));
JLabel lbl = monoLabel(title, 9, FG_TEXT);
lbl.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, BORDER_COL));
p.add(lbl, BorderLayout.NORTH);
return p;
}
private JButton sideBtn(String text, Color fgColor) {
JButton btn = new JButton(text);
btn.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 8));
btn.setBackground(new Color(0x11, 0x11, 0x11));
btn.setForeground(fgColor);
btn.setBorder(BorderFactory.createLineBorder(BORDER_COL));
btn.setMaximumSize(new Dimension(Integer.MAX_VALUE, 28));
return btn;
}
private static JLabel monoLabel(String text, int size, Color fg) {
JLabel l = new JLabel(text);
l.setFont(new Font(Font.MONOSPACED, Font.PLAIN, size));
l.setForeground(fg);
return l;
}
// ── Viewport panel — 3D wireframe renderer ────────────────────────────────
class ViewportPanel extends JPanel {
final Random rng = new Random();
// Rotation matrix (3×3, row-major)
private float[] rot = {1,0,0, 0,1,0, 0,0,1};
// Mouse state for drag-to-rotate
private int lastMX, lastMY;
private boolean dragging;
// Auto-computed scale (fits manifold to panel)
private float scale = 0f; // 0 = needs recompute
private float camDist = 3000f;
// Pre-allocated per-frame buffers — avoids GC pressure during spin
private float[] rv = new float[3]; // rotation scratch
private float[] sxBuf = new float[0]; // projected x
private float[] syBuf = new float[0]; // projected y
private float[] szBuf = new float[0]; // projected z (depth)
// Pre-allocated strokes
private final BasicStroke wireStroke = new BasicStroke(0.5f);
private final BasicStroke seamStroke = new BasicStroke(1.5f);
ViewportPanel() {
setBackground(BG_SCENE);
MouseAdapter ma = new MouseAdapter() {
@Override public void mousePressed(MouseEvent e) {
lastMX = e.getX(); lastMY = e.getY(); dragging = true;
}
@Override public void mouseReleased(MouseEvent e) { dragging = false; }
@Override public void mouseDragged(MouseEvent e) {
if (!dragging) return;
float dx = (e.getX() - lastMX) * 0.008f;
float dy = (e.getY() - lastMY) * 0.008f;
lastMX = e.getX(); lastMY = e.getY();
rotateX(dy);
rotateY(dx);
repaint();
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
void resetScale() { scale = 0f; }
@Override
protected void paintComponent(Graphics g0) {
super.paintComponent(g0);
Graphics2D g = (Graphics2D)g0;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (!manifold.built) {
g.setColor(new Color(0x33, 0x33, 0x33));
g.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 10));
g.drawString("AWAITING_SEEDS — draw on overlay or type in PCB", 20, getHeight()/2);
return;
}
int W = getWidth(), H = getHeight();
float cx = W / 2f, cy = H / 2f;
// auto-scale once per build
if (scale == 0f) {
float[] bb = manifold.bounds();
float span = Math.max(
Math.max(bb[3]-bb[0], bb[4]-bb[1]),
bb[5]-bb[2]
);
scale = Math.min(W, H) * 0.35f / Math.max(span, 1f);
camDist = span * 3f;
}
int M = Manifold.M;
// Resize projection buffers only when vertex count changes
if (sxBuf.length < manifold.vertexCount) {
sxBuf = new float[manifold.vertexCount];
syBuf = new float[manifold.vertexCount];
szBuf = new float[manifold.vertexCount];
}
// Project all vertices (no allocation inside loop)
for (int i = 0; i < manifold.vertexCount; i++) {
rotateVecInto(
manifold.positions[i*3],
manifold.positions[i*3+1],
manifold.positions[i*3+2],
rv
);
szBuf[i] = rv[2];
float w = camDist / (rv[2] + camDist);
sxBuf[i] = cx + rv[0] * scale * w;
syBuf[i] = cy - rv[1] * scale * w;
}
// Draw wireframe grid (u-lines and v-lines)
g.setColor(WIRE_COL);
g.setStroke(wireStroke);
// u-lines: for each u, draw edges along v
for (int u = 0; u < M; u++) {
for (int v = 0; v < M - 1; v++) {
int a = u*M+v, b = u*M+(v+1);
g.drawLine(Math.round(sxBuf[a]), Math.round(syBuf[a]),
Math.round(sxBuf[b]), Math.round(syBuf[b]));
}
}
// v-lines: for each v, draw edges along u
for (int v = 0; v < M; v++) {
for (int u = 0; u < M - 1; u++) {
int a = u*M+v, b = (u+1)*M+v;
g.drawLine(Math.round(sxBuf[a]), Math.round(syBuf[a]),
Math.round(sxBuf[b]), Math.round(syBuf[b]));
}
}
// Draw seam (diagonal u==v) in red
g.setColor(SEAM_COL);
g.setStroke(seamStroke);
for (int u = 0; u < M - 1; u++) {
int a = u*M+u, b = (u+1)*M+(u+1);
g.drawLine(Math.round(sxBuf[a]), Math.round(syBuf[a]),
Math.round(sxBuf[b]), Math.round(syBuf[b]));
}
// Draw friends
for (Friend f : friends) {
rotateVecInto(f.x, f.y, f.z, rv);
float w = camDist / (rv[2] + camDist);
int fx = Math.round(cx + rv[0] * scale * w);
int fy = Math.round(cy - rv[1] * scale * w);
g.setColor(FRIEND_COLORS[f.idx]);
g.fillOval(fx - 6, fy - 6, 12, 12);
}
// Flicker overlay on opacity — draw subtle sine pulse as bottom label
float alpha = 0.3f + (float)Math.sin(tick * flickerRate) * 0.2f;
g.setColor(new Color(0f, 0f, 0f, Math.max(0f, Math.min(1f, alpha))));
g.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 8));
g.setColor(new Color(0x33, 0x33, 0x33));
g.drawString(String.format("tick=%d seeds=%d heat_max=%.2f",
tick, seedPoints.size(),
manifold.heat.length > 0 ? maxHeat() : 0f), 8, H - 8);
}
private float maxHeat() {
float m = 0;
for (float v : manifold.heat) if (v > m) m = v;
return m;
}
// Apply rotation matrix into a pre-allocated float[3] — no allocation
private void rotateVecInto(float x, float y, float z, float[] out) {
out[0] = rot[0]*x + rot[1]*y + rot[2]*z;
out[1] = rot[3]*x + rot[4]*y + rot[5]*z;
out[2] = rot[6]*x + rot[7]*y + rot[8]*z;
}
// Rotate around X axis by angle (radians)
private void rotateX(float angle) {
float c = (float)Math.cos(angle), s = (float)Math.sin(angle);
float[] rx = {1,0,0, 0,c,-s, 0,s,c};
rot = mulMat(rx, rot);
}
// Rotate around Y axis by angle (radians)
private void rotateY(float angle) {
float c = (float)Math.cos(angle), s = (float)Math.sin(angle);
float[] ry = {c,0,s, 0,1,0, -s,0,c};
rot = mulMat(ry, rot);
}
private float[] mulMat(float[] a, float[] b) {
float[] r = new float[9];
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
for (int k = 0; k < 3; k++)
r[row*3+col] += a[row*3+k] * b[k*3+col];
return r;
}
}
// ── Draw overlay — seed point canvas ─────────────────────────────────────
class DrawOverlay extends JPanel {
private final List<float[]> dots = new ArrayList<>();
DrawOverlay() {
setOpaque(true);
setBackground(new Color(255, 255, 255, 180));
setBorder(BorderFactory.createLineBorder(BORDER_COL));
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
MouseAdapter ma = new MouseAdapter() {
@Override public void mousePressed(MouseEvent e) { dot(e); }
@Override public void mouseDragged(MouseEvent e) { dot(e); }
private void dot(MouseEvent e) {
float x = e.getX(), y = e.getY();
dots.add(new float[]{x, y});
seedPoints.add(new float[]{x, y});
repaint();
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
void addDot(float x, float y) {
dots.add(new float[]{x, y});
repaint();
}
void clear() {
dots.clear();
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
for (float[] d : dots) g.fillRect((int)d[0], (int)d[1], 2, 2);
}
}
}