news 2026/7/22 12:32:47

基于自制类弦理论的物理模拟

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于自制类弦理论的物理模拟

基本实体:宇宙的基本实体是旋转的线段。线段属性:线段突然出现 → 逐渐缩短 → 消失。线段有颜色,颜色在拼接时色散,分配到相邻线段。线段会旋转,旋转速度与平移速度成反比,线段是局部时间的具象化:线段的存在与消失对应局部时间的产生与流逝。2. 结构假设,拼接结构:线段通过离散拼接构成网络。拼接处有节点,节点约束旋转幅度。拼接必定扭曲。引力本质:线段网络的结构体现为引力,节点处的约束与色散传递对应引力相互作用,空间生成:线段碰到空间边界会使边界向外扩散,空间由此膨胀。3. 宇宙初始条件,初始宇宙是一个球体,球内每个整数坐标点产生一条线段。 线段消失后,同一位置会有新线段补充(守恒或循环)。<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<title>自定义引力线段模拟器</title>

<style>

body { margin: 0; display: flex; flex-direction: column; align-items: center; background: #000; color: #fff; font-family: Arial; }

#canvas { border: 2px solid #444; background: #111; }

.controls { margin: 10px 0; display: flex; gap: 10px; align-items: center; }

button { padding: 5px 15px; cursor: pointer; background: #333; color: #fff; border: 1px solid #666; }

input { width: 100px; padding: 5px; background: #222; color: #fff; border: 1px solid #666; }

</style>

</head>

<body>

<div class="controls">

<label>时间倍数:</label>

<input type="number" id="timeScale" value="1" min="0.1" step="0.1">

<button onclick="resetSim()">重置模拟</button>

</div>

<canvas id="canvas" width="800" height="600"></canvas>

<script>

const canvas = document.getElementById('canvas');

const ctx = canvas.getContext('2d');

let timeScale = 1;

let segments = [];

let polygons = [];

const MAX_SEGMENTS = 200;

const NODE_DIST = 15;

const MAX_LIFE = 100; // 线段最大生命周期

class Segment {

constructor(x, y) {

this.x = x; this.y = y;

this.len = Math.random() * 30 + 20;

this.angle = Math.random() * Math.PI * 2;

this.angleSpeed = (Math.random() - 0.5) * 0.02;

this.lenDecay = 0.01;

this.color = `hsl(${Math.random() * 360}, 80%, 50%)`;

this.nodes = [{x: this.x, y: this.y}, this.getEndPoint()];

this.life = MAX_LIFE; // 新增:生命周期

}

getEndPoint() {

return {

x: this.x + Math.cos(this.angle) * this.len,

y: this.y + Math.sin(this.angle) * this.len

};

}

update() {

this.angle += this.angleSpeed * timeScale;

this.len -= this.lenDecay * timeScale;

this.life -= 1 * timeScale; // 生命周期随时间减少

// 生命周期耗尽或长度过短则重置

if (this.life <= 0 || this.len < 5) {

this.len = Math.random() * 20 + 10;

this.life = MAX_LIFE;

this.color = `hsl(${Math.random() * 360}, 80%, 50%)`;

}

this.nodes[1] = this.getEndPoint();

// 颜色亮度随生命周期调整

const hue = parseInt(this.color.match(/hsl\((\d+)/)[1]);

const alpha = this.life / MAX_LIFE; // 透明度与生命周期正相关

this.displayColor = `hsla(${hue}, 80%, 50%, ${alpha})`;

}

draw() {

// 线段颜色使用带透明度的displayColor,不再是黑色

ctx.beginPath();

ctx.moveTo(this.nodes[0].x, this.nodes[0].y);

ctx.lineTo(this.nodes[1].x, this.nodes[1].y);

ctx.strokeStyle = this.displayColor;

ctx.lineWidth = 2;

ctx.stroke();

// 节点绘制

this.nodes.forEach(node => {

ctx.beginPath();

ctx.arc(node.x, node.y, 3, 0, Math.PI * 2);

ctx.fillStyle = `rgba(255,255,255,${this.life/MAX_LIFE})`;

ctx.fill();

});

}

}

function checkCollisionAndMerge() {

const nodeMap = new Map();

segments.forEach((seg, segIdx) => {

seg.nodes.forEach((node, nodeIdx) => {

const key = `${Math.round(node.x / NODE_DIST)}_${Math.round(node.y / NODE_DIST)}`;

if (!nodeMap.has(key)) nodeMap.set(key, []);

nodeMap.get(key).push({seg, node, segIdx, nodeIdx});

});

});

for (const [key, nodes] of nodeMap) {

if (nodes.length < 2) continue;

const vertices = nodes.map(item => item.node);

const uniqueVerts = vertices.filter((v, i) =>

vertices.findIndex(u => u.x === v.x && u.y === v.y) === i

);

if (uniqueVerts.length >= 3) {

// 多边形透明度随线段平均生命周期调整

const avgLife = nodes.reduce((sum, item) => sum + item.seg.life, 0) / nodes.length;

const polyColor = nodes[0].seg.displayColor.replace(/[^,]+(?=\))/, avgLife/MAX_LIFE);

polygons.push({ vertices: [...uniqueVerts], color: polyColor });

nodes.forEach(item => item.seg.angleSpeed *= 0.5);

}

}

}

function drawPolygons() {

polygons.forEach(poly => {

ctx.beginPath();

ctx.moveTo(poly.vertices[0].x, poly.vertices[0].y);

poly.vertices.forEach(v => ctx.lineTo(v.x, v.y));

ctx.closePath();

ctx.fillStyle = poly.color.replace('50%,', '20%,');

ctx.strokeStyle = poly.color;

ctx.lineWidth = 1;

ctx.fill();

ctx.stroke();

});

if (polygons.length > 50) polygons.shift();

}

function initSim() {

segments = [];

polygons = [];

for (let i = 0; i < MAX_SEGMENTS; i++) {

const x = Math.floor(Math.random() * (canvas.width - 40)) + 20;

const y = Math.floor(Math.random() * (canvas.height - 40)) + 20;

segments.push(new Segment(x, y));

}

}

function resetSim() {

initSim();

}

function animate() {

ctx.clearRect(0, 0, canvas.width, canvas.height);

timeScale = parseFloat(document.getElementById('timeScale').value) || 1;

segments.forEach(seg => seg.update());

segments.forEach(seg => seg.draw());

checkCollisionAndMerge();

drawPolygons();

requestAnimationFrame(animate);

}

window.addEventListener('resize', () => {

canvas.width = Math.min(window.innerWidth - 40, 800);

canvas.height = Math.min(window.innerHeight - 100, 600);

});

initSim();

animate();

</script>

</body>

</html>

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/22 4:07:46

前端图片水印神器:watermark.js完全指南 [特殊字符]

在当今数字化时代&#xff0c;前端图片水印已成为保护图片版权的必备技术。作为一款纯浏览器端的水印处理库&#xff0c;watermark.js让开发者能够轻松实现浏览器水印功能&#xff0c;无需依赖任何服务器端处理。本教程将带你从零开始掌握这个强大的工具。 【免费下载链接】wat…

作者头像 李华
网站建设 2026/7/22 1:08:40

低代码不止省开发时间:重构企业数字化转型的成本结构

引言&#xff1a;跳出“工具思维”&#xff0c;看见低代码的成本革命不少企业误将低代码仅视为“缩短开发周期的工具”&#xff0c;却忽视其重构数字化转型成本结构的核心价值。面对“转型投入高、回报慢”的困境&#xff0c;低代码正以全链路成本优化能力&#xff0c;打破传统…

作者头像 李华
网站建设 2026/7/22 1:55:02

Cursor免费试用重置完全指南:告别设备限制困扰

Cursor免费试用重置完全指南&#xff1a;告别设备限制困扰 【免费下载链接】go-cursor-help 解决Cursor在免费订阅期间出现以下提示的问题: Youve reached your trial request limit. / Too many free trial accounts used on this machine. Please upgrade to pro. We have th…

作者头像 李华
网站建设 2026/7/21 18:19:25

Unity游戏开发架构完整指南:依赖注入与高内聚低耦合设计实战

Unity游戏开发架构完整指南&#xff1a;依赖注入与高内聚低耦合设计实战 【免费下载链接】Zenject 项目地址: https://gitcode.com/gh_mirrors/zen/Zenject 在Unity游戏开发中&#xff0c;如何构建可维护、可扩展且易于测试的代码架构是每个团队都面临的挑战。传统开发…

作者头像 李华
网站建设 2026/7/22 10:03:49

WebLogic:如何扩展access.log日志的输出字段

WebLogic的access.log是非常重要的日志&#xff0c;它记录了有哪些HTTP请求访问过此应用服务器&#xff0c;但也有一些比较重要的信息没有记录&#xff0c;比如请求耗时等。下面来看一下怎样才能扩展access.log的输出字段。 登录WebLogic管理控制台&#xff0c;进入【环境】>…

作者头像 李华