文档
DSL 基础
理解场景、实体、连接、约束和展示语句。
PhysLoom DSL 追求描述物理模型,而不是描述 SVG。一个模型通常由五层信息组成:场景、实体、连接、物理参数和展示要求。
场景
每个模型从 scene 开始:
scene inclined_plane
// 后面依次写实体和关系
场景名用于识别模型,不会自动成为图上的标题。
实体
实体是模型中的对象。常见实体包括 body、support、pulley、surface、spring、charge 和电路元件。
load crate 8kg
support ceiling orientation=horizontal
surface ramp incline 30deg
spring S 120N/m
标识符应简短且唯一。显示给读者的文字可以另外设置,不必把一整句塞进标识符。
连接和路径
连接说明对象之间的关系。对于常见滑轮系统,只声明滑轮的附着关系就够了:
load A 2kg
load B 3kg
pulley P
support ceiling
P <-> ceiling
编译器会推导经过 P 且与轮缘相切的绳路,并把它纳入绳长约束。只有多根绳或特殊路径使拓扑产生歧义时,才需要显式声明具名绳路。
参数和单位
数值应带单位:
| 量 | 示例 |
|---|---|
| 质量 | mass=2kg |
| 距离 | distance=0.5m |
| 角度 | angle=30deg |
| 劲度系数 | stiffness=120N/m |
编译器会把单位归一化后再求解。不要用名称代替单位,也不要把 1kg 写成图上的纯文本来规避模型参数。
导轨上的导体棒可以穿过一段有限磁场:
field B magnetic 1T direction=into_page x_min=1.5m x_max=3.5m
两个端点都以导轨左端为原点,必须位于导轨范围内。区间外 B 为零;省略两个端点则表示
磁场覆盖整个装置。当前只支持一根棒向右运动、闭合纯电阻回路,不表示任意粒子或波的边界模型。
可以打开穿过磁场的综合题,只修改 x_max 做对比。
定义一次,显式复用
同一数值用于不同声明时,用 let 定义,用 $name 引用:
scene matched_lamp
let supply = 6V
source V $supply
lamp L $supply 3W
V <-> L <-> V
修改 supply 会同时改变电源电压和灯泡额定电压。若只想改变供电电压,灯泡额定值应独立填写。
共享参数表示作者主动声明的数值相等,不表示编译器自动推断了物理耦合。
引用可用于具名属性、简写和动作数值,例如
motor M rated_voltage=$supply no_load_speed=60rad/s resistance=1ohm。
电动起重机综合题 已使用这种跨领域写法。
参数只属于当前场景,可以在引用后声明,也可以写 let nominal = $supply 作为别名。
重复定义、未知引用和循环引用都会报错。值仅支持有限数字、物理量或另一个参数;
不支持字符串、宏、循环和算术表达式。实际使用处仍检查量纲及范围,质量不能当作透镜焦距。
量纲相同而含义不同的属性仍须具名,不能依靠参数名称猜测物理含义。
$F 明确引用已定义的数值,裸写 F 在支持符号的模型里仍是待求量。
实体名称、引号内的文字和颜色不做参数替换。格式化、分享和源码导出都会保留 let 和 $name。
属性和值的类型
属性名写在 = 左边,运行时语言定义会约束右边可以填写的值。编辑器的校验、自动补全和速记参数解析都读取同一份定义。
| 值类型 | 接受的内容 | 示例 |
|---|---|---|
枚举 enum | 定义中列出的有限选项 | state=closed |
标识符 identifier | 对象名称、方向名称或其他可引用名称 | field=EM、direction=down |
物理量 quantity | 数值和匹配量纲的单位 | mass=2kg、angle=30deg |
物理量或符号 quantity-or-symbol | 具体物理量,或暂不求值的符号 | wavelength=500nm、wavelength=lambda |
无单位数字 number | 不带单位的数值 | amplitude=0.5 |
文本 text | 普通标识符或带引号的文字 | label="main lamp" |
任意值 any | 扩展语句暂未收窄的值 | 通常不需要直接依赖 |
enum 和 identifier 不同:枚举只接受列出的选项;标识符是开放名称。编辑器可以为标识符提供常用建议,但建议列表不会把它变成枚举。
力学、光学、电路、波、热学流体及现代物理的实体使用同一套领域定义驱动的简写。只有一个待填的简写属性时,输入会直接归给它并进行校验;有多个候选时,编译器根据值类型和物理量纲寻找唯一匹配,因此下面两种写法等价:
lamp L 6V 3W
lamp L 3W 6V
同样的规则也能省去常见模型中重复的属性名:
body block 1kg
pendulum P 0.6m 10deg
lens L converging 10cm
object candle 4cm subject=candle
fluid water 1000kg/m3
reservoir hot 600K
lens L 10cm converging 与上面的透镜定义等价,也可以混用具名属性。
值的先后顺序不决定物理含义;只有语言参考中列出的简写属性参与匹配,并非所有属性都省略名称。
在 Studio 中,将鼠标悬停在属性值上,或把光标放在值内按 F1,可查看其绑定的属性和说明。
例如灯泡的 6V 显示 rated_voltage=6V;$supply 还会显示当前解析出的数值。
按 Escape 关闭说明;编辑源码时旧提示自动关闭。说明读取已有语言定义,不改写源码,
也不会为无效输入猜测属性绑定。
有歧义的量仍然具名:弹簧原长与位移都是长度,导轨长度与间距也都是长度;
静摩擦和动摩擦因数都没有单位。应该写
spring S 16N/m rest_length=1m displacement=0.2m,
不能写 spring S 16N/m 1m 0.2m。name=value 是正常 DSL 写法,不是旧语法兼容层。
展示要求
show 对象名 请求已声明对象的常用展示信息,不改变物理模型,也不会启动动画:
load cargo
rope R
show cargo R
对绳子而言,show R 请求显示张力。课程需要特定结果时,可写 show cargo.displacement 或 show cargo.force_diagram。这些信息来自同一份求解结果,关闭展示不会改变绳长约束或受力关系。不写 show 也会绘制对象本身。
样例中的展示选择统一写成一行,例如 show cargo R。默认详情符合需要时直接写对象名;
只需要部分详情时保留 .feature。默认图示已经满足课程需要时,不必添加 show,
也不要仅为缩短源码而改成 .all。
用 show cargo.all 请求该对象全部可用的详情;多个对象可用空格或逗号分隔,例如
show cargo.all, R.all。只显示当前模型和渲染器支持的内容,不补造缺失结果,也不启动动画。
输入 show cargo. 后,编辑器会提示 cargo.all 和各个单项详情;悬停在选择项上可查看含义。
用颜色突出对象
在实体末尾添加颜色即可改变它的视觉强调,不会改变材料或物理参数:
load cargo 20kg #gold
pulley M #blue
force effort 100N direction=down #red
可用颜色由 语言参考 自动列出。只有需要给绳子的不同线段分别着色时,才需要显式写出具名绳路。
写得更短,物理含义不变
场的类型和强度可以省去属性名:
field B magnetic 1T direction=into_page
field E electric 200V/m direction=right
1T 按单位映射到 magnetic_strength,200V/m 映射到 electric_strength。
类型和物理量可以交换顺序,也可以继续写完整的 name=value。
声明可以直接带上常用的 on 关系:
force pull 1N direction=right on bar
body crate 1kg on ramp
这些是片段,需要在同一场景中声明 bar 和 ramp。第一句等价于
force pull 1N direction=right 加上 pull on bar。
实体属性放在 on 前,作用位置等关系参数(如 position=1cm)放在目标后。
其他关系写成独立的结构行或具名物理模型:
body ball 1kg
launch flight body=ball origin=ground speed=20m/s angle=45deg
object candle 4cm
imaging view object=candle optic=L object_distance=30cm
还需在同一场景中声明 ground 和光学元件 L。flight、view 是模型名称,
不能与实体或其他模型重名。body、origin、object、optic 等参与者角色名
由各模型的语言定义规定。已声明物体和透镜时,也可用
candle -> L object_distance=30cm 表达成像关系。
滚动使用具名 rolling 模型,trajectory 的重复阶段写成
stages=(ramp, floor, S)。完整模型见模型配方。
统一的动画写法
所有动画都使用 animate。duration 表示实验运行多久,speed 表示播放倍速:
animate duration=3s speed=0.5
这表示实验运行 3 秒,以 0.5 倍速观看,屏幕播放 6 秒。speed=1 是正常速度,
speed=2 是两倍速;省略时默认为 1。倍速不改变轨迹、受力或实验读数。
无目标的时间区间适用于直线运动、小角度摆、弹簧振子、导体棒综合案例、 电动提升和叠块装置。一个连通系统只写一条区间动画,各物体共享同一物理时钟。
如果想看“滑到 1 米为止”,不需要事先知道要多久:
scene incline_arrival
surface ramp incline 12deg smooth
body crate 1kg on ramp
animate crate until crate.displacement == 1m speed=1
show crate.motion crate.forces
until 表示首次满足条件就结束。这一例从静止开始,重力决定加速度,约 0.99 秒后到达;
speed=0.5 只把观看速度减半。位移相对初始位置计算,沿斜面向下为正,向上为负。
0m 在起点已满足,因此保持静态;静摩擦阻止运动或方向不对时会报错。
目前此条件支持斜面上的单个滑动或滚动物体(包括纯滚动和滑移滚动);滚动终点暂只支持顺坡方向。
水平直线运动可用 animate car until car.displacement == 40m speed=1;位移相对初始 x,向右为正。若物体折返,动画在首次到达时结束;达不到的终点会报错。双物体共用同一时钟,例如 animate A until A.displacement == 60m speed=1 会同时观察 A、B 到 A 首次移动 60 米;不写 until 的 animate A 仍在相遇时结束。
固定轴转动可用 animate wheel until wheel.turn == 360deg speed=1 表示累计转过一圈;turn 不是圆盘朝向,转动方向和到达时间由力矩决定。
小角单摆从静止释放时,可用 animate P until P.angle == 8deg speed=1 观察首次到达 8°。
这里的角度是相对竖直向下的绝对角度,向右为正,终值必须在起始振幅内;animate P speed=1 仍表示观察完整自然周期。
无阻尼自由弹簧振子可用 animate weight until weight.offset == 0m speed=1,
首次到达平衡位置时结束,历时四分之一个周期。offset 是相对平衡位置的有符号距离,
向下为正,不是相对起点的 displacement。目前只支持单弹簧、无阻尼、无外力且无刚度调制的情形。
光电效应可用 animate electron until electron.displacement == 10nm 指定电子逸出后的观察距离;光子到达材料的时间也计入动画。0nm 表示不播放动画。未列出的模型暂不支持。
输入 until 后编辑器会提示可用物理量和单位;终值也可引用 $参数。
until 和 duration 二选一,条件后只写可选的 speed,不能再指定运动轨迹。
删除动画语句,物体仍处于相同的初始位置。
也可以指定对象,观察模型已有的事件或周期,或给出一个支持的参数终值:
animate P speed=0.5
animate candle object_distance=15cm duration=3s speed=1
animate R.free distance=1m duration=2s speed=1
以上是三个独立示例:分别观察摆的一个周期、改变物距、规定绳端运动。
不写 duration 时,模型决定结束时刻,例如落地、相遇或一个周期。相遇本身不代表碰撞。
若模型已经决定事件时长,显式时长必须与之相符,不能强迫物体提前落地;
要改变观看节奏,只改 speed。
弹簧由阻尼、外力和刚度调制决定响应;周期外力目前使用稳态响应,不含启动瞬态。
变刚度振子没有保证的周期终点,需要 animate duration=3s speed=1 指定观察区间。
自由、阻尼和受迫弹簧振子相对平衡位置的读数跟随模型轨迹,不做线性估算。
场线、电流、波形和能量账本也使用同一个命令和倍速。静态场线与直流电流点是示意进度,
不是粒子运动,不接受物理 duration;speed=1 使用默认的演示节奏。波和交流相位保留
频率决定的真实周期,因此高速现象可能需要很小的倍速,如 speed=1e-8。
热机账本沿已声明的时序展示能量收支,不是热力学路径仿真。
旧稿的动作和 playback 暂时兼容;新内容统一使用 animate 与 speed。
何时指定布局
默认先让布局器寻找清楚且不重叠的位置。只有题目确实依赖特定构图时,再添加布局提示。布局提示应该表达相对关系,例如“在右侧”或“保持竖直”,而不是依赖某个屏幕尺寸的绝对像素。
这条边界很重要:模型说物理事实,布局说怎样看清这些事实。
要看不同物理领域如何复用这套结构,可以继续阅读 常用模型写法。