

一、设计思路
上一篇讲了动画怎么"动",这一篇讲数据怎么"变":四象限动画不只是视觉绕圈,每一帧都要产出可观察、可验证的数据流。数据链路是:角度 θ → 波点坐标 (x, y) → 两条直线在 x 处的值 y₁、y₂ → 差值 Δy = |y₁ − y₂| → 象限遍历序列。最终让一个教学结论"显形":Δy = 0 时,波点的 x 正是两直线交点横坐标(方程组的解)。
二、数据链路总览
setInterval(40ms)
│
├─ θ += 2° ──────────────→ @State angle (角度)
│
├─ x = 4cosθ, y = 4sinθ ─→ @State dotX/dotY (坐标)
│
├─ 符号判定 ─────────────→ @State dotQuadrant (象限)
│
├─ y₁ = k₁x + b₁ ────────→ @State y1 (直线1 值)
│ y₂ = k₂x + b₂ ────────→ @State y2 (直线2 值)
│ Δy = |y₁ − y₂| ───────→ @State deltaY (差值)
│
└─ 象限切换 ─────────────→ @State quadLog (遍历序列)
每一环都是上一环的纯函数,@State 层层接力,UI 面板自动刷新。
三、每帧的数据计算(核心代码)
@State angle: number = 0;
@State dotX: number = 4;
@State dotY: number = 0;
@State y1: number = 4; // 直线1 在波点 x 处的值
@State y2: number = 0; // 直线2 在波点 x 处的值
@State deltaY: number = 4; // |y1 - y2|
@State quadLog: string = 'Ⅰ ';
private yOf1(x: number): number { return this.k1 * x + this.b1; }
private yOf2(x: number): number { return this.k2 * x + this.b2; }
// 动画步进:坐标 → 双直线值 → 差值 → 象限序列
private tick(): void {
this.angle += 2;
if (this.angle >= 360) {
this.angle = 0;
}
const rad = this.angle * Math.PI / 180;
this.dotX = 4 * Math.cos(rad); // 1. 坐标由角度生成
this.dotY = 4 * Math.sin(rad);
const q = this.quadrantOf(this.dotX, this.dotY);
if (q !== this.dotQuadrant) { // 2. 象限切换才记录
this.recordQuadrant(q);
this.dotQuadrant = q;
}
this.y1 = this.yOf1(this.dotX); // 3. 两直线在 x 处的取值
this.y2 = this.yOf2(this.dotX);
this.deltaY = Math.abs(this.y1 - this.y2); // 4. 差值
this.drawQuad(); // 5. 重绘
}
四、数据面板 UI(@State 自动刷新)
// 动画实时数据面板:无需手动 setState,@State 一变 UI 自动重渲染
Row({ space: 10 }) {
Column({ space: 4 }) {
Text('角度 θ').fontSize(12).fontColor('#9CA3AF')
Text(this.angle + '°')
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#10B981')
}.layoutWeight(1)
Column({ space: 4 }) {
Text('坐标 (x, y)').fontSize(12).fontColor('#9CA3AF')
Text('(' + this.dotX.toFixed(1) + ', ' + this.dotY.toFixed(1) + ')')
.fontSize(13).fontWeight(FontWeight.Bold).fontColor('#10B981')
}.layoutWeight(1.4)
Column({ space: 4 }) {
Text('所在象限').fontSize(12).fontColor('#9CA3AF')
Text(this.dotQuadrant)
.fontSize(13).fontWeight(FontWeight.Bold).fontColor('#7C3AED')
}.layoutWeight(1.2)
}.width('100%').margin({ top: 4 })
Row({ space: 10 }) {
Column({ space: 4 }) {
Text('直线1 值 y₁').fontSize(12).fontColor('#9CA3AF')
Text(this.y1.toFixed(1))
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#4C7DFF')
}.layoutWeight(1)
Column({ space: 4 }) {
Text('直线2 值 y₂').fontSize(12).fontColor('#9CA3AF')
Text(this.y2.toFixed(1))
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#F59E0B')
}.layoutWeight(1)
Column({ space: 4 }) {
Text('差值 Δy = |y₁−y₂|').fontSize(12).fontColor('#9CA3AF')
Text(this.deltaY.toFixed(1))
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#EF4444')
}.layoutWeight(1)
}.width('100%').margin({ top: 4 })
Text('象限遍历序列:' + this.quadLog)
.fontSize(12).fontColor('#6B7280').width('100%')
五、数据变化中的数学洞察
1. 坐标的连续性:角度每帧 +2°,cos/sin 输出连续变化,面板上的 (x, y) 数字平滑滚动——这正是"函数值随自变量连续变化"的直观呈现。
2. Δy = 0 的时刻:当波点 x 恰为两直线交点横坐标时,y₁ = y₂,Δy = 0。用户会观察到面板上红色 Δy 数值周期性逼近 0——此时对照"交点"Canvas 上的红点位置,代数解与几何点对上了。
3. 象限序列的周期性:绕行一圈,quadLog 追加出 Ⅰ Ⅱ Ⅲ Ⅳ Ⅰ Ⅱ Ⅲ Ⅳ ...,周期 360°,四个象限顺序恒定——符号规律从静态表格变成动态证据。
| 观察时刻 | angle | 坐标 | 象限 | y₁ | y₂ | Δy |
|---|---|---|---|---|---|---|
| θ=0° | 0 | (4.0, 0) | Ⅰ | 4.0 | 0.0 | 4.0 |
| θ=60° | 60 | (2.0, 3.5) | Ⅰ | 2.0 | 2.0 | 0.0 |
| θ=90° | 90 | (0.0, 4.0) | Ⅱ | 0.0 | 4.0 | 4.0 |
| θ=180° | 180 | (−4.0, 0) | Ⅲ | −4.0 | 8.0 | 12.0 |
| θ=270° | 270 | (0.0, −4) | Ⅳ | 0.0 | 4.0 | 4.0 |
(示例参数:k₁=1, b₁=0;k₂=−1, b₂=4,交点为 x=2。)
六、代码要点
- 单向数据流:角度是唯一输入,其余全部派生,杜绝多变量互相改写的混乱。
- 纯函数计算:
yOf1/yOf2/quadrantOf无副作用,输入 x 必得唯一输出,可测试。 - @State 接力:每帧改 5 个 @State,ArkUI 自动做最小化 diff 更新,性能无忧。
- 教学闭环:数据面板与两幅 Canvas(直线交点图 + 四象限动画图)共享同一套参数,三处信息永远自洽。
七、数据与知识点对照
| 动画数据 | 对应数学概念 |
|---|---|
| 角度 θ | 自变量(连续变化) |
| 坐标 (x, y) | 点的位置(函数值) |
| 象限 | 坐标符号的定性结论 |
| y₁ / y₂ | 两个一次函数在 x 处的值 |
| Δy = 0 | 两函数值相等 → 交点横坐标 → 方程组解 |
| 遍历序列 | 符号规律在运动中的周期性重现 |
八、扩展思路
- 差值可视化:可在 Canvas 中把 Δy 画成波点 x 处的竖直线段,数据变图形。
- 交点提示:当 |Δy| < 0.3 时让波点变红、数据面板高亮,提示"接近交点"。
- 轨迹曲线:把 y₁−y₂ 作为第三条曲线的 y,画出"差值曲线",零点即解。
- 变速观察:滑块控制角度增量,慢速细看交点时刻的数据跳变。
数据与动画同源、同频、同步——这正是"四象限动画数据变化"想传递的:数学不是静态公式,而是每帧都在流动的数据。

51

被折叠的 条评论
为什么被折叠?



