开发工具数据可视化【免费下载链接】penroseCreate beautiful diagrams just by typing notation in plain text.项目地址https://gitcode.com/gh_mirrors/pe/penrose点击查看免费下载导读本文以 Penrose 官方教程一的 4 道进阶挑战为主线完整讲解如何在.domain、.substance、.style三个文件中分别定义集合类型、声明集合实例、并通过forall选择器与Circle/Rectangle形状把数学对象渲染成图。读完本文你将掌握三文件协作的思维模式并能独立写出多形状、带描边、含未知参数?的 Style 程序同时理解这些语法背后的 Shape 默认属性与采样机制。背景Penrose 的程序三元组是什么Penrose 的理念是只输入数学记号自动生成美观示意图。每个 Penrose 程序都由三个文件组成官方教程 basics.md 称之为三元组 triple.domain定义领域词汇表例如存在一种对象叫Set集合.substance声明这张图具体要画哪些对象例如画集合 A、B、C.style决定这些对象长什么样例如集合一律画成圆/正方形/矩形。三者职责分离.substance管画什么.domain管词汇表.style管怎么画。同一个.domain与.style可以配多个.substance生成不同内容的图反过来同一批 substance 也能用不同 style 渲染出截然不同的视觉风格。仓库中教程一的 starter 代码位于 packages/examples/src/tutorials/code/tutorial1/包含三个文件setTheory.domain空白 domain等待你写出type SettwoSets.style预设了canvas { width 0; height 0 }注释提示替换为真实宽高等待你补全选择器twoSets.substance空白 substance等待你声明Set A、Set B。官方完整 walkthrough 见 packages/docs-site/docs/tutorial/basics.md本文对应的标准答案即 packages/examples/src/tutorials/solutions/tutorial1.md。下面从 Challenge 1 到 Challenge 4 逐题展开每道题都会给出完整的三个文件内容。运行环境如何把三件套跑起来在开始做题前先确认运行方式。根据 packages/examples/src/tutorials/README.md本地调试需要两个终端窗口均在仓库根目录下操作终端一执行yarn start持续监听core的改动并构建终端二使用rogerCLI 监听三件套文件命令格式为npx roger watch substance文件 style文件 domain文件以教程一 starter 代码为例npx roger watch packages/examples/src/tutorials/code/tutorial1/twoSets.substance packages/examples/src/tutorials/code/tutorial1/twoSets.style packages/examples/src/tutorials/code/tutorial1/setTheory.domainroger是 Penrose 官方的命令行工具见 packages/roger/README.md 与 packages/docs-site/docs/ref/using.md。除了watch还可以用roger trio xxx.trio.json一次性从 trio 配置生成 SVG——仓库为教程一提供了现成的 tutorial1.trio.json其内容指向上述三个 starter 文件{ substance: ./code/tutorial1/twoSets.substance, style: [./code/tutorial1/twoSets.style], domain: ./code/tutorial1/setTheory.domain, variation: }如果你的改动把某个文件内容替换成了下方答案重新编译即可看到对应效果。每次点resample或更换variation种子Penrose 会重新采样并优化出一个新布局——这正是下文要反复提到的未指定属性由引擎自动决定的体现。Challenge 1把两个集合扩展成三个集合第一道题的目标最简单图上原本有两个圆代表两个集合现在再加一个Set让画布上出现 3 个圆。.domain与.style保持不变只需要改.substance。.domaintype Set.stylecanvas { width 800 height 700 } forall Set x { x.icon Circle { strokeWidth : 0.0 } }With changes:.substanceSet A Set B Set C逐行解读.domain中用type Set声明集合是一种对象类型Penrose 才知道 substance 里Set A的Set是什么。类型名大小写完全由你决定type set则对应set A本文沿用官方的Set。.style顶部的canvas块声明画布尺寸为800 × 700。Penrose 要求每个 Style 文件都在顶部声明画布参见 shapes-overview.md。forall Set x { ... }是选择器selector对 substance 程序中每一个类型为Set的对象把该对象绑定到风格变量x然后执行块体。其匹配语义详见 selectors.md——编译器会为x逐一生成到 substance 对象的映射并触发块体这里Set A/B/C会触发 3 次。x.icon Circle { strokeWidth : 0.0 }把集合对象渲染为一个Circle。字段名icon是自定义的叫shape、foo都行只要赋值为 Shape 对象Penrose 就会把该对象绘制出来。strokeWidth : 0.0表示不要描边——事实上Circle的strokeWidth默认值就是0见下文源码写出来只是更显式。Challenge 2用正方形表示集合第二题保持 3 个集合不变但把视觉表示从圆换成正方形且边长固定为 50.0。注意 Penrose 并没有内置Square类型——正方形就是长宽相等的Rectangle。本题只改.style。.substanceSet A Set B Set C.domaintype SetWith changes:.stylecanvas { width 800 height 700 } forall Set x { x.icon Rectangle { width : 50.0 height : 50.0 } }为什么用 Rectangle 而不是 SquarePenrose 内置形状只有Circle、Ellipse、Rectangle、Line、Path、Polygon、Polyline、Text、Equation、Image、Group等形状类型清单见 packages/core/src/shapes/Shapes.ts。当 width 与 height 相等时Rectangle在视觉上就是正方形。这里显式给出width : 50.0、height : 50.0边长是固定常量优化器不会再调整这两个量。从源码看 Rectangle 的默认属性在 packages/core/src/shapes/Rectangle.ts 的sampleRectangle中可以看到一个Rectangle的完整属性包括name、strokeWidth默认0、strokeStyle默认solid、strokeColor默认无笔触、strokeDasharray、fillColor默认随机采样、center默认在画布范围内随机采样、width/height默认在[3, 画布尺寸/6]内随机采样见 Samplers.ts 的sampleWidth/sampleHeight、cornerRadius默认0、rotation默认0、ensureOnCanvas默认true。也就是说当你只指定width和height时矩形的位置center与填充色fillColor依然由 Penrose 随机采样后自动优化因此每次重新采样都会得到不同的布局这是 Penrose 的正常行为。Challenge 3给矩形加描边与随机颜色第三题同样保持 3 个集合把集合画成描边宽度为 15的矩形。Hint 提示需要同时设置strokeColor官方答案用的是sampleColor(0.5, rgb)。本题也只改.style。.substanceSet A Set B Set C.domaintype SetWith changes:.stylecanvas { width 800 height 700 } forall Set x { x.icon Rectangle { strokeColor : sampleColor(0.5, rgb) strokeWidth : 15.0 } }sampleColor随机但固定的颜色sampleColor(alpha, colorType)是 Penrose 内置函数其正式定义位于 packages/core/src/lib/Functions.tssampleColor条目Sample a random color once, with opacityalphaand color typecolorType(rgborhsv).参数含义参数取值说明alpha01 的数值透明度/不透明度colorTypergb或hsv颜色模型选择rgb时引擎分别从[0.1, 0.9]均匀采样 R、G、B 三个通道alpha 取你传入的值对应实现见 Samplers.ts 的sampleColor与Functions.ts中的makeInput采样逻辑选择hsv时色相从[0, 360]均匀采样饱和度与明度类似处理。需要注意sampleColor生成的是一组随机但固定的常量只与当前variation种子有关它不像?那样参与优化。这与 random-sampling.md 中随机采样值表现得像常量的原则一致——描边颜色会随 resample 改变但不会在优化过程中被调整。strokeWidth : 15.0则是固定常量直接把描边加粗到 15。Challenge 4一个 Set 同时渲染为圆和正方形第四题是技巧性最强的一题保持 3 个集合但每个集合同时画一个圆和一个正方形画布上总共出现 6 个对象。关键在于一个 style 块体里可以给同一个对象绑定多个 Shape 字段x.circle与x.squarePenrose 会把它们都画出来引入未知值?正方形的边长让引擎来定再让圆和正方形共用这个边长提示见 basics.md 的 Challenge 4you will need to initialize another Shape object!。.substanceSet A Set B Set C.domaintype SetWith changes:.stylecanvas { width 800 height 700 } forall Set x { x.side ? x.circle Circle { } x.square Rectangle { width : x.side height : x.side } }未知值?是什么?是 Style 语言中的未知标量表达式。根据 expressions.md 的说明The?expression evaluates to a scalar whose value is automatically determined by the Penrose engine. The Penrose engine picks a random initial value in place of?and runs an optimization process to adjust it to a more suitable value.即x.side ?表示这个量由 Penrose 决定引擎先给它一个随机初始值然后在优化阶段结合ensureOnCanvas等约束把它调整到合适大小。由于x.square的宽高都引用x.side圆与正方形在优化中被联动起来。如果需要给优化器一个初始值提示可以写成?[3.14]这种形式方括号内必须是固定常量?[1 1]是不允许的。一个对象两个 Shape 字段x.circle Circle { }括号为空意味着所有属性都用默认值半径r由sampleWidth随机采样画布 800 宽时在[3, 800/6]即约 3133 之间取值见 Circle.ts 与 Samplers.ts位置center随机采样fillColor随机采样strokeWidth默认0。x.square则显式引用x.side保证是正方形。最终效果3 个集合 ×1 圆 1 正方形 画布上 6 个对象。深入理解Shape 默认属性与自动布局原理做完 4 道题后有几个底层机制值得总结它们决定了为什么代码这么少、图却这么完整。1. 每个 Shape 都有默认属性以Circle为例packages/core/src/shapes/Circle.ts 的sampleCircle给出完整默认属性strokeWidth: 0、strokeStyle: solid、strokeColor: none()不画描边、fillColor: sampleColor(...)随机填充色、center: sampleVector(...)画布范围内随机、r: sampleWidth(...)随机半径、ensureOnCanvas: true。这就是 Challenge 1 中Circle { strokeWidth : 0.0 }也能画出完整圆形的原理——你只声明了少数属性其余全部走默认值并参与优化。完整属性表见 shapes/circle.md 与 shapes/rectangle.md。2. ensureOnCanvas 与自动布局所有形状都有ensureOnCanvas属性默认true它是一条特殊约束保证形状始终落在canvas声明所定义的画布边界内见 shapes-overview.md。这也是x.side ?这类未知值能被自动摆好的关键Penrose 会跑一个优化过程让未知参数与位置在满足ensureOnCanvas等约束的前提下达到合理布局。3. forall 选择器的匹配机制forall Set x { ... }不是循环遍历而是匹配编译器把风格变量x映射到 substance 程序中的每个Set对象逐个执行块体详细匹配算法见 selectors.md。因此3 个集合触发 3 次块体产生 3 组独立形状如果想给满足特定关系的对象单独定制样式可以在选择器中追加where子句例如官方教程二的写法forall Set x; Set y where Subset(x, y) { ... }见 solutions/tutorial2.md这是下一步进阶的内容。4. 只改 style 就够了的关注点分离Challenge 24 中.substance与.domain完全没变只有.style在变。这印证了三文件架构的设计意图substance描述有哪些数学对象style决定怎么把它们画出来。同一个Set A/B/C既能画成 3 个圆也能画成 3 个 50×50 的正方形还能圆方共存——视觉表达与数学内容彻底解耦。仓库中的 set-theory-domain/functions.domain 还提供了更丰富的集合论词汇Intersection、Union、Subset、Intersecting等后续教程如 tutorial2 的Subset、tutorial3 的向量空间就是在这一基础上逐步叠加的。小结与下一步回顾 4 道挑战你实际上已经掌握了 Penrose 入门最重要的四组能力三文件分工.domain定义类型、.substance声明实例、.style渲染样式三者缺一不可选择器语法forall 类型 变量 { ... }让每种 substance 对象获得统一视觉形状与属性Circle/Rectangle的常用属性strokeWidth、strokeColor、width、height与默认值机制以及sampleColor随机颜色函数未知值?把尺寸、位置等交给 Penrose 的优化引擎自动求解这是自动布局的核心开关。标准答案完整版始终保存在 solutions/tutorial1.mdstarter 代码在 code/tutorial1/官方图文教程在 packages/docs-site/docs/tutorial/basics.md。接下来推荐按顺序进入教程二Subset谓词与ensure约束参考 solutions/tutorial2.md和教程三向量空间与函数构造参考 solutions/tutorial3.md它们会在本文的基础上引入谓词匹配、ensure/encourage约束与override覆盖等更强大的机制。赞分享开发工具数据可视化【免费下载链接】penroseCreate beautiful diagrams just by typing notation in plain text.项目地址https://gitcode.com/gh_mirrors/pe/penrose点击查看免费下载相关推荐TREK MCP Scopes 完全指南27 个 OAuth 权限的作用域、推导规则与最小授权实战TREK MCP Scopes 完全指南27 个 OAuth 权限的作用域、推导规则与最小授权实战 TREK 通过 MCPModel Context Pro开发工具数据可视化Penrose 实战指南用 Domain–Substance–Style 三语言纯文本绘制集合论欧拉图Penrose 实战指南用 Domain–Substance–Style 三语言纯文本绘制集合论欧拉图 Penrose 是一个只靠纯文本符号就能生成高质量图开发工具数据可视化gpui-kit Avatar 头像组件实战指南图片回退、OkLCH 自动配色与 AvatarGroup 分组gpui kit Avatar 头像组件实战指南图片回退、OkLCH 自动配色与 AvatarGroup 分组 Avatar 是 gpui kit基于 GP开发工具数据可视化上一篇抖音创作者必备如何轻松批量保存所有视频内容下一篇抖音批量下载助手高效获取用户所有视频的完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考