惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google DeepMind News
Google DeepMind News
T
Tenable Blog
博客园_首页
S
Securelist
Spread Privacy
Spread Privacy
Google Online Security Blog
Google Online Security Blog
Forbes - Security
Forbes - Security
Engineering at Meta
Engineering at Meta
U
Unit 42
L
LINUX DO - 热门话题
量子位
T
Threat Research - Cisco Blogs
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
K
Kaspersky official blog
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
The Last Watchdog
The Last Watchdog
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
Martin Fowler
Martin Fowler
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Security Latest
Security Latest
Scott Helme
Scott Helme
V
Vulnerabilities – Threatpost
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
Know Your Adversary
Know Your Adversary
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
T
The Blog of Author Tim Ferriss
aimingoo的专栏
aimingoo的专栏
V2EX - 技术
V2EX - 技术
T
Tailwind CSS Blog
月光博客
月光博客
Recent Announcements
Recent Announcements
G
Google Developers Blog
F
Full Disclosure
W
WeLiveSecurity
宝玉的分享
宝玉的分享
腾讯CDC
G
GRAHAM CLULEY
Vercel News
Vercel News
Simon Willison's Weblog
Simon Willison's Weblog
美团技术团队
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次 安卓APP通话记录与录音上传踩坑记录 - 子舒的博客 天量下跌 inBox 笔记 2.3.8,把工具栏交给了你-咕咚同学 我把小龙虾搬到了微信-咕咚同学 安好 - 响石潭 Compound Engineering Plugin:让每个工程单元都比上一个更容易 MOSS-TTS Family:开源高质量语音与声音生成模型家族深度解析 Crawl4AI:专为 LLM 设计的开源 Web 爬虫与数据抓取工具 Build Your Own X:从零实现你最喜欢的技术——程序员进阶的终极资源清单 Anthropic Skills:用文件夹教 Claude 专业技能的开源框架 1年的去月球(下) - 梅之夏 欢迎回来。 简单讲讲 ASN.1 与 OID DTV - 直播聚合客户端 5.22-5.27 – 不兴江 还没去过鸭川 – 不兴江 张晶晶同学三刷林志颖 关于我 – 不兴江 爱与嫉妒 – 不兴江 港股被持续做空 备案码花了四百块-咕咚同学 一句话生成封面:我给公众号做了4种风格的AI封面生成技能 「官」方認證 再谈费曼学习法 2026-05-28T00:34:11+08:00 2026-05-28T00:28:45+08:00 离谱的英语学习指南:基于AI的英语进阶系统方法论 iii:零集成架构的后端统一运行时 Claude Code Harness:让 Claude Code 工作有迹可循的工程化框架 Heretic:全自动移除大语言模型审查机制的开源工具 MarkItDown:微软开源的万能文档转 Markdown 利器 Harness:让 Claude Code 秒变多智能体协作工厂 这段时间尽折腾AI Agent了,确实极大地提高了效率 近期动态:两个新站点正式上线啦 误判解除!zhouayuan.com 腾讯安全申诉成功 - 周阿源|玩具设计・插画日常・生活随笔 Ralph:让 AI 编码工具自主循环跑完所有 PRD 任务的量产神器 全都违法 – 个人工作记录 关于zhouayuan.com被误判 “含违规信息” 的说明与申诉记录 - 周阿源|玩具设计・插画日常・生活随笔 小米 MiMo v2.5 Pro 白嫖 最大的人间清醒,兜里有钱,但是不花。 夜晚靓歌(12):于文文现场solo - 王志勇的Blog 今日插画:风扬起的倔强 - 周阿源|玩具设计・插画日常・生活随笔 回门习俗 独立网卡 - 忘记了回忆 500亿入股人工智能企业 从命令行到桌面智能体-咕咚同学 第一性原理读书笔记 行者微评论223-加班の守株待兔-博客|政治与时事-风雨行者 ZOZO开源物理接触求解器:GPU加速的可扩展仿真引擎 OpenStock:开源股票市场交易平台技术深度解析 MoneyPrinterTurbo:基于AI的全自动短视频生成工具深度解析 Claude-Mem:为 Claude Code 构建的持久化记忆压缩系统 Twenty:可代码化定制的企业级开源 CRM 平台技术深度解析 2026-05-26T22:59:17+08:00 企业级开源大模型部署平台 GPUStack 实战教程 1年的去月球(上) - 梅之夏 Sevalla - 静态网站托管服务 不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code 装修灯具要注意⚠️ 黄梅天先锋 - 游子微博 公安备案顺利办结,站点备案全部完成 - 周阿源|玩具设计・插画日常・生活随笔 第三次兑换天猫超市卡了宗宗酱-三维狐少儿编程 Don't think, feel. - Rolen's Blog 人这一辈子,到底图个什么 博客迁移 - Edwin's Blog 情感赛道写作模板 再现本轮行情的典型特征 裁员与平常心-咕咚同学 别让“偷懒”,成为隐私泄露的破绽 片刻 - Jdeal | Life is like a Design.
d3-force-3d 构建时预计算 3D 网络布局,减少客户端渲染压力 | 姓王者的博客
作者:xingwangzhe · 2026-06-28 · via BlogFinder

🕒 阅读时间:4 分钟📝 字数:1237👀 阅读量:Loading...

前言

友链图谱 是一个汇聚了 1600+ 节点2200+ 连接的 3D 友链网络可视化项目。数据源是 links/*.yml 文件,渲染层基于 3d-force-graph(Three.js + d3-force-3d)。

上一篇文章中,我介绍了友链图谱从 2D 升级到 3D 的整体架构——包括 3D 力导布局的数学原理、节点渲染和高亮系统。但那时的方案是:构建时只输出数据,客户端自行跑力导仿真

这个方案有两个痛点:

痛点 表现
加载慢 每次刷新都要从 [-5,5] 随机位置重新跑动画
hover 卡顿 每次悬停触发 Graph.refresh() → 遍历 1600 节点计算颜色
构建浪费 构建 2 秒完成,但客户端要跑 5-10 秒动画

声明:本文在撰写过程中使用了 AI 工具辅助分析技术资料、整理踩坑经验及润色排版。

思路:构建时预计算位置

「既然 d3-force-3d 在客户端跑,那在构建时(Node.js)也跑一遍不就提前拿到位置了吗?」

d3-force-3d 官方文档明确支持这种做法:

simulation.tick() — "This method can be used in conjunction with simulation.stop to compute a static force layout."

于是我在 Astro API 端点 graph.json.ts 中加入了构建时预计算:

import { forceSimulation, forceLink, forceManyBody, forceCenter } from "d3-force-3d";

const sim = forceSimulation(nodes, 3) // 明确 3 维!

.force(

"link",

forceLink(links)

.id((d) => d.id)

.distance(30),

)

.force("charge", forceManyBody().strength(-60))

.force("center", forceCenter(0, 0, 0)) // 默认 strength=1

.alphaDecay(0.02)

.velocityDecay(0.3);

for (let i = 0; i < 300; i++) sim.tick();

sim.stop();

客户端改成加载预计算位置,直接冻结:

.cooldownTicks(0)

.cooldownTime(0)

然而……事情没那么简单。

踩坑 1:平面坍塌

跑出来的效果:

X: std=635 范围 [-1780, 1594]

Y: std=523 范围 [-2107, 1317]

Z: std=141 范围 [-200, 200] ← 被压扁了!

3D ratio = 0.223 ⚠️ 扁平

Z 轴被压到只有 ±200,不管怎么调参数——distance=30 还是 40charge=-60 还是 -120alphaDecay=0.02 还是 0.005——Z 永远塌在初始半径以内。

原因forceCenter(0,0,0) 的默认强度是 1.0,而 charge 只有 -60link 只有 distance=30。center 力比其他力大了两个数量级,强行把所有节点往原点拉,Z 轴首当其冲被消解。

有趣的是,客户端渲染时同样的参数看起来却是"3D 网络"——因为客户端跑到 200 tick 就停了(cooldownTicks),还没收敛到平面,停在了一个好看的暂态。但构建时要的是一劳永逸,不能依赖"没跑完"。

踩坑 2:花哨尝试一一失败

方案 结果
forceRadial(800).strength(0.05) 强制球壳,不是网络
自定义 zBias 力(随机 Z 扰动) 被 alpha 衰减消解,Z 还是塌
去掉 forceCenter,只用 forceX/forceY 中心节点子节点形成圆盘
forceCenter.strength(0.3) 0.651,不够

每次调整都离目标差一点,走了很多弯路。

最终方案:三轴等强 + 弱居中

关键洞察是:不要对抗 forceCenter,而是把它减弱到和其他力一个量级

const sim = forceSimulation(nodes, 3)

.force(

"link",

forceLink(links)

.id((d) => d.id)

.distance(40),

)

.force("charge", forceManyBody().strength(-120))

.force("center", forceCenter(0, 0, 0).strength(0.02)) // ← 关键!

.alphaDecay(0.01)

.velocityDecay(0.4);

for (let i = 0; i < 500; i++) sim.tick();

sim.stop();

参数 作用
link.distance 40 连接节点间距
charge -120 排斥力(比默认强一倍)
center.strength 0.02 极弱居中,仅防漂移
alphaDecay 0.01 慢冷却,充分收敛
velocityDecay 0.4 与 3d-force-graph 默认对齐
tick 500 完全跑完

为什么 0.02 有效?

strength=0.02 意味着每 tick 所有节点只向中心移动 2% 的距离。这刚好抵消整体漂移,但完全不足以压倒 link 和 charge 力。三种力在同一个量级上互相平衡,自然形成 3D 散布。

结果:

X: std=478 范围 [-1288, 1265]

Y: std=312 范围 [-640, 1315]

Z: std=357 范围 [-1076, 802]

3D ratio = 0.747 ✅ 良好的 3D 网络

三轴散布均衡,没有平面、没有球壳、没有圆盘,是一个真正的体积网络(volumetric network)。

客户端配置

客户端直接加载预计算位置,不再跑额外仿真:

.graphData(graphData)

.warmupTicks(0)

.cooldownTicks(0)

.cooldownTime(0)

.d3AlphaDecay(0.02)

.d3VelocityDecay(0.3);

注意 linkcharge不能禁用d3Force(null)),否则 3d-force-graph 的连线渲染会丢失。只要 cooldownTicks(0),仿真在一 tick 后立即冻结,位置不会被挪动。

效果对比

指标 客户端渲染 构建时预计算
页面加载 等 5-10 秒动画 即开即用
构建时间 2 秒 20 秒(一次编译,永久使用)
hover 卡顿 有(Graph.refresh) 无(已优化)
3D 散布 暂态,依赖 timing 稳定
布局可复现 ❌ 每次随机 ✅ 固定(只要 seed 不变)

总结

构建时预计算 3D 力导布局完全可行,关键不是"要不要用 forceCenter",而是把 forceCenter 的强度降到和其他力一个量级

center.strength 结果
1.0 平面(center 主宰)
0.0 漂移(无约束)
0.02 3D 网络 ✅(三种力平衡)

项目仓库:xingwangzhe/FriendLinks — 欢迎 star 和 PR!

友链图谱在线体验:https://links.needhelp.icu/