在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、设计思路

动滑轮与定滑轮相反:省一半力,但费一倍距离,且不能改变力的方向。实际计算还要考虑滑轮自重:F = (G + G轮) / 2。页面做成"动滑轮计算器"——输入物重、滑轮自重、提升高度,实时算出实际拉力、理想拉力(G/2)与绳子移动距离,并与定滑轮(F = G)对比,直观看到"省了多大力、多走了多少距离"。

二、状态与计算函数

import { router } from '@kit.ArkUI';

@Entry
@Component
struct MovablePulley {
  @State weight: number = 100;         // 物重 G(N)
  @State pulleyWeight: number = 10;    // 动滑轮自重 G轮(N)
  @State liftHeight: number = 2;       // 提升高度 h(m)

  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);

  // 实际拉力:考虑滑轮自重,两段绳子分担
  private forceWithPulley(): number {
    return (this.weight + this.pulleyWeight) / 2;
  }

  // 理想拉力:忽略滑轮重(初中最常见考法)
  private forceIdeal(): number {
    return this.weight / 2;
  }

  // 绳子移动距离:费一倍距离
  private ropeDistance(): number {
    return this.liftHeight * 2;
  }
}

三、Canvas 绘制动滑轮(绳固定端 + 绕轮 + 上拉)

  private draw(): void {
    const ctx = this.ctx;
    const w = ctx.width;
    const h = ctx.height;
    ctx.clearRect(0, 0, w, h);
    const cx = w * 0.5;
    const cy = 96;   // 轮心(也是物体悬挂点)

    // 天花板与绳固定端(左上角)
    ctx.strokeStyle = '#9CA3AF';
    ctx.lineWidth = 3;
    ctx.beginPath(); ctx.moveTo(w * 0.08, 26); ctx.lineTo(w * 0.92, 26); ctx.stroke();
    ctx.beginPath(); ctx.moveTo(w * 0.3, 26); ctx.lineTo(cx - 26, cy); ctx.stroke();

    // 动滑轮(轮心随物体升降)
    ctx.strokeStyle = '#8B5CF6';
    ctx.lineWidth = 4;
    ctx.beginPath(); ctx.arc(cx, cy, 26, 0, Math.PI * 2); ctx.stroke();
    ctx.fillStyle = '#8B5CF6';
    ctx.beginPath(); ctx.arc(cx, cy, 5, 0, Math.PI * 2); ctx.fill();

    // 绳子绕轮:固定端 → 轮左 → 轮顶 → 轮右 → 竖直向上拉出
    ctx.strokeStyle = '#4C7DFF';
    ctx.lineWidth = 3;
    ctx.beginPath();
    ctx.moveTo(cx - 26, cy);              // 轮左边缘
    ctx.arc(cx, cy, 26, Math.PI, 0);      // 沿轮上缘(弧度 π→0)
    ctx.lineTo(cx + 26, cy - 46);         // 右绳向上
    ctx.stroke();

    // 拉力箭头(向上)
    this.arrow(cx + 26, cy - 16, cx + 26, cy - 58, '#10B981');
    ctx.fillStyle = '#10B981';
    ctx.font = '12px sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('F=(G+G轮)/2 向上', cx + 26, cy - 68);

    // 物体挂在轮轴下
    ctx.fillStyle = '#6B7280';
    ctx.fillRect(cx - 18, cy + 26, 36, 34);
    ctx.fillStyle = Color.White;
    ctx.fillText('G=' + this.weight + 'N', cx, cy + 48);
  }

四、UI 与实时对比结果

  build() {
    Column() {
      // 顶部标题栏(略)
      Scroll() {
        Column({ space: 14 }) {
          // 公式卡
          Text('F = (G + G轮) / 2  S = 2h')
            .fontSize(18).fontWeight(FontWeight.Bold)
            .fontColor('#7C3AED').width('100%').textAlign(TextAlign.Center)

          Canvas(this.ctx)
            .width('100%').height(220)
            .onReady(() => { this.draw(); })

          // 三个参数输入行:TextInput + Number() 转换
          Column({ space: 12 }) {
            Row({ space: 10 }) {
              Text('物重 G(N)').fontSize(14).fontColor('#111827').layoutWeight(1)
              TextInput({ text: this.weight.toString() })
                .width(110).height(36).type(InputType.Number)
                .onChange((v: string) => { this.weight = Number(v) || 0; })
            }.width('100%')
            // 滑轮自重、提升高度两行同理(略)
          }
          .width('100%').padding(16).borderRadius(16)
          .backgroundColor(Color.White).border({ width: 1, color: '#E5EAF2' })

          // 结果对比卡:三列数据(实际拉力 / 理想拉力 / 绳长)
          Column({ space: 8 }) {
            Text('⚖️ 计算结果').fontSize(15).fontWeight(FontWeight.Bold)
              .fontColor('#111827').width('100%')
            Row({ space: 10 }) {
              Column({ space: 4 }) {
                Text('实际拉力').fontSize(12).fontColor('#9CA3AF')
                Text(this.forceWithPulley().toFixed(1) + ' N')
                  .fontSize(20).fontWeight(FontWeight.Bold).fontColor('#7C3AED')
              }.layoutWeight(1)
              Column({ space: 4 }) {
                Text('理想拉力 G/2').fontSize(12).fontColor('#9CA3AF')
                Text(this.forceIdeal().toFixed(1) + ' N')
                  .fontSize(20).fontWeight(FontWeight.Bold).fontColor('#7C3AED')
              }.layoutWeight(1)
              Column({ space: 4 }) {
                Text('绳子移动 S').fontSize(12).fontColor('#9CA3AF')
                Text(this.ropeDistance().toFixed(1) + ' m')
                  .fontSize(20).fontWeight(FontWeight.Bold).fontColor('#7C3AED')
              }.layoutWeight(1)
            }.width('100%').margin({ top: 4 })

            // 与定滑轮对比:省了多少力
            Text('对比定滑轮 F=' + this.weight + 'N:动滑轮省了 '
              + (this.weight - this.forceWithPulley()).toFixed(1) + 'N,但绳子多走一倍距离')
              .fontSize(13).fontColor('#4B5563').lineHeight(20).width('100%')
          }
          .width('100%').padding(16).borderRadius(16)
          .backgroundColor('#F3E8FF').border({ width: 1, color: '#E9D5FF' })
        }
        .padding(14)
      }
      .layoutWeight(1).scrollBar(BarState.Off)
    }
    .height('100%').width('100%').backgroundColor('#F4F6FA')
  }

五、代码要点

  • 纯函数计算forceWithPulley / forceIdeal / ropeDistance 三个只读函数即"物理公式",UI 调用展示。
  • 弧线绕轮ctx.arc(cx, cy, 26, Math.PI, 0) 从 π 到 0 画上半圆,模拟绳子绕过轮顶,注意与直线段的接续。
  • 输入容错Number(v) || 0 防止空字符串转 NaN 导致计算崩溃。
  • 对比教学:结果卡把"动滑轮实际拉力"与"定滑轮 F=G"放同一屏,省力数值一眼可见。

六、动滑轮核心知识点

要点 内容
特点 省一半力、费一倍距离(S = 2h)、不能改变力的方向
理想情况 F = G/2(忽略滑轮自重与摩擦)
实际情况 F = (G + G轮) / 2,滑轮越重越费力
本质 动力臂 = 2 × 阻力臂的省力杠杆(支点在绳固定端)
机械效率 η = W有/W总 = Gh/Fs = G / (G + G轮)
应用 起重机、滑轮组(动滑轮省力 + 定滑轮改向)
易错 拉力方向只能向上;省力不省功(功的原理:任何机械都不省功)
口诀 动滑轮,力一半;距离长,方向不换
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐