1. 全等三角形判定器
  • 功能:用户输入三边或两边一角,系统判断是否能判定全等(SSS, SAS, ASA等),并高亮对应边角。
    输入界面:提供两个三角形的边长和角度输入字段
    自动判定:实时判断两个三角形是否全等
    判定方法:支持 SSS、SAS、ASA、AAS、HL 等判定方法
    可视化显示:在 Canvas 中绘制两个三角形,并高亮显示判定依据
    结果展示:显示判定结果和使用的判定方法
    在这里插入图片描述
**
 * 三角形全等判定工具
 * 功能:用户输入三边或两边一角,系统判断是否能判定全等(SSS, SAS, ASA等),并高亮对应边角
 */
// 三角形数据接口
interface TriangleData {
  a: number
  b: number
  c: number
  A: number
  B: number
  C: number
}

@Entry
@Component
struct CongruentTriangles {
  // 三角形1的边长
  @State sideA1: string = ''
  @State sideB1: string = ''
  @State sideC1: string = ''
  @State angleA1: string = ''
  @State angleB1: string = ''
  @State angleC1: string = ''
  
  // 三角形2的边长
  @State sideA2: string = ''
  @State sideB2: string = ''
  @State sideC2: string = ''
  @State angleA2: string = ''
  @State angleB2: string = ''
  @State angleC2: string = ''
  
  // 判定结果
  @State result: string = ''
  @State method: string = ''
  @State highlightSides: string[] = []
  @State highlightAngles: string[] = []
  
  // 画布配置
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  
  build() {
    Scroll() {
      Column({ space: 20 }) {
        // 标题
        Text('三角形全等判定工具')
          .fontSize(28)
          .fontWeight('Bold')
          .textAlign(TextAlign.Center)
        
        // 功能介绍
        Text('输入两个三角形的边长或角度,系统将自动判断是否全等,并高亮显示判定依据')
          .fontSize(14)
          .fontColor('#666')
          .textAlign(TextAlign.Center)
          .width('90%')
        
        // 三角形1输入区域
        Column() {
          Text('三角形 1')
            .fontSize(18)
            .fontWeight('Bold')
            .margin({ bottom: 10 })
          
          Grid() {
            GridItem() {
              Column() {
                Text('边长 A')
                TextInput({ text: this.sideA1 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.sideA1 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('角度 A')
                TextInput({ text: this.angleA1 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.angleA1 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('边长 B')
                TextInput({ text: this.sideB1 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.sideB1 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('角度 B')
                TextInput({ text: this.angleB1 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.angleB1 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('边长 C')
                TextInput({ text: this.sideC1 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.sideC1 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('角度 C')
                TextInput({ text: this.angleC1 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.angleC1 = val
                    this.judgeCongruence()
                  })
              }
            }
          }
          .columnsTemplate('1fr 1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
        }
        .width('90%')
        .padding(15)
        .backgroundColor('#FFFFFF')
        .borderRadius(10)
        
        // 三角形2输入区域
        Column() {
          Text('三角形 2')
            .fontSize(18)
            .fontWeight('Bold')
            .margin({ bottom: 10 })
          
          Grid() {
            GridItem() {
              Column() {
                Text('边长 A')
                TextInput({ text: this.sideA2 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.sideA2 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('角度 A')
                TextInput({ text: this.angleA2 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.angleA2 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('边长 B')
                TextInput({ text: this.sideB2 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.sideB2 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('角度 B')
                TextInput({ text: this.angleB2 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.angleB2 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('边长 C')
                TextInput({ text: this.sideC2 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.sideC2 = val
                    this.judgeCongruence()
                  })
              }
            }
            GridItem() {
              Column() {
                Text('角度 C')
                TextInput({ text: this.angleC2 })
                  .width(80)
                  .height(40)
                  .onChange((val) => {
                    this.angleC2 = val
                    this.judgeCongruence()
                  })
              }
            }
          }
          .columnsTemplate('1fr 1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
        }
        .width('90%')
        .padding(15)
        .backgroundColor('#FFFFFF')
        .borderRadius(10)
        
        // 判定结果
        Column() {
          Text('判定结果')
            .fontSize(18)
            .fontWeight('Bold')
            .margin({ bottom: 10 })
          
          Text(this.result)
            .fontSize(16)
            .fontColor(this.result.includes('全等') ? '#4CAF50' : '#F44336')
            .textAlign(TextAlign.Center)
          
          if (this.method) {
            Text(`判定方法:${this.method}`)
              .fontSize(14)
              .fontColor('#666')
              .margin({ top: 5 })
          }
        }
        .width('90%')
        .padding(15)
        .backgroundColor('#F5F5F5')
        .borderRadius(10)
        
        // 三角形可视化
        Column() {
          Text('三角形可视化')
            .fontSize(18)
            .fontWeight('Bold')
            .margin({ bottom: 10 })
          
          Canvas(this.context)
            .width('90%')
            .height(300)
            .backgroundColor('#FFFFFF')
            .borderRadius(10)
            .onReady(() => {
              this.drawTriangles()
            })
        }
        
        // 使用说明
        Column() {
          Text('使用说明')
            .fontSize(18)
            .fontWeight('Bold')
            .margin({ bottom: 10 })
          
          Text('1. 输入两个三角形的边长或角度')
            .fontSize(14)
            .fontColor('#666')
          Text('2. 系统会自动判断是否全等')
            .fontSize(14)
            .fontColor('#666')
          Text('3. 全等的边角会在图中高亮显示')
            .fontSize(14)
            .fontColor('#666')
          Text('4. 支持的判定方法:SSS, SAS, ASA, AAS, HL')
            .fontSize(14)
            .fontColor('#666')
        }
        .width('90%')
        .padding(15)
        .backgroundColor('#F5F5F5')
        .borderRadius(10)
      }
      .width('100%')
      .padding(20)
      .backgroundColor('#F0F4F8')
    }
  }
  
  // 判定三角形全等
  private judgeCongruence() {
    // 清空之前的结果
    this.result = ''
    this.method = ''
    this.highlightSides = []
    this.highlightAngles = []
    
    // 解析输入值
    const s1: TriangleData = {
      a: parseFloat(this.sideA1),
      b: parseFloat(this.sideB1),
      c: parseFloat(this.sideC1),
      A: parseFloat(this.angleA1),
      B: parseFloat(this.angleB1),
      C: parseFloat(this.angleC1)
    }
    
    const s2: TriangleData = {
      a: parseFloat(this.sideA2),
      b: parseFloat(this.sideB2),
      c: parseFloat(this.sideC2),
      A: parseFloat(this.angleA2),
      B: parseFloat(this.angleB2),
      C: parseFloat(this.angleC2)
    }
    
    // 检查输入是否足够
    const validSides1 = [s1.a, s1.b, s1.c].filter(v => !isNaN(v)).length
    const validAngles1 = [s1.A, s1.B, s1.C].filter(v => !isNaN(v)).length
    const validSides2 = [s2.a, s2.b, s2.c].filter(v => !isNaN(v)).length
    const validAngles2 = [s2.A, s2.B, s2.C].filter(v => !isNaN(v)).length
    
    if (validSides1 < 3 && (validSides1 + validAngles1) < 3) {
      this.result = '请输入足够的边长或角度'
      this.drawTriangles()
      return
    }
    
    if (validSides2 < 3 && (validSides2 + validAngles2) < 3) {
      this.result = '请输入足够的边长或角度'
      this.drawTriangles()
      return
    }
    
    // SSS 判定
    if (!isNaN(s1.a) && !isNaN(s1.b) && !isNaN(s1.c) && 
        !isNaN(s2.a) && !isNaN(s2.b) && !isNaN(s2.c)) {
      const sides1 = [s1.a, s1.b, s1.c].sort((a, b) => a - b)
      const sides2 = [s2.a, s2.b, s2.c].sort((a, b) => a - b)
      
      if (this.isEqual(sides1[0], sides2[0]) && 
          this.isEqual(sides1[1], sides2[1]) && 
          this.isEqual(sides1[2], sides2[2])) {
        this.result = '两个三角形全等'
        this.method = 'SSS (边边边)'
        this.highlightSides = ['a', 'b', 'c']
        this.drawTriangles()
        return
      }
    }
    
    // SAS 判定
    if (!isNaN(s1.a) && !isNaN(s1.b) && !isNaN(s1.C) && 
        !isNaN(s2.a) && !isNaN(s2.b) && !isNaN(s2.C)) {
      if (this.isEqual(s1.a, s2.a) && 
          this.isEqual(s1.C, s2.C) && 
          this.isEqual(s1.b, s2.b)) {
        this.result = '两个三角形全等'
        this.method = 'SAS (边角边)'
        this.highlightSides = ['a', 'b']
        this.highlightAngles = ['C']
        this.drawTriangles()
        return
      }
    }
    
    // ASA 判定
    if (!isNaN(s1.A) && !isNaN(s1.B) && !isNaN(s1.c) && 
        !isNaN(s2.A) && !isNaN(s2.B) && !isNaN(s2.c)) {
      if (this.isEqual(s1.A, s2.A) && 
          this.isEqual(s1.c, s2.c) && 
          this.isEqual(s1.B, s2.B)) {
        this.result = '两个三角形全等'
        this.method = 'ASA (角边角)'
        this.highlightSides = ['c']
        this.highlightAngles = ['A', 'B']
        this.drawTriangles()
        return
      }
    }
    
    // AAS 判定
    if (!isNaN(s1.A) && !isNaN(s1.B) && !isNaN(s1.a) && 
        !isNaN(s2.A) && !isNaN(s2.B) && !isNaN(s2.a)) {
      if (this.isEqual(s1.A, s2.A) && 
          this.isEqual(s1.B, s2.B) && 
          this.isEqual(s1.a, s2.a)) {
        this.result = '两个三角形全等'
        this.method = 'AAS (角角边)'
        this.highlightSides = ['a']
        this.highlightAngles = ['A', 'B']
        this.drawTriangles()
        return
      }
    }
    
    // HL 判定(直角三角形)
    if ((!isNaN(s1.C) && this.isEqual(s1.C, 90)) && 
        (!isNaN(s2.C) && this.isEqual(s2.C, 90)) && 
        !isNaN(s1.a) && !isNaN(s1.b) && 
        !isNaN(s2.a) && !isNaN(s2.b)) {
      const hyp1 = Math.max(s1.a, s1.b)
      const leg1 = Math.min(s1.a, s1.b)
      const hyp2 = Math.max(s2.a, s2.b)
      const leg2 = Math.min(s2.a, s2.b)
      
      if (this.isEqual(hyp1, hyp2) && this.isEqual(leg1, leg2)) {
        this.result = '两个直角三角形全等'
        this.method = 'HL (斜边直角边)'
        this.highlightSides = ['a', 'b']
        this.highlightAngles = ['C']
        this.drawTriangles()
        return
      }
    }
    
    // 无法判定全等
    this.result = '无法判定全等'
    this.drawTriangles()
  }
  
  // 绘制三角形
  private drawTriangles() {
    const ctx = this.context
    const width = 360
    const height = 300
    
    // 清空画布
    ctx.clearRect(0, 0, width, height)
    
    // 绘制三角形1
    this.drawTriangle(ctx, 100, 150, 200, 150, 100, 100, '三角形 1', 1)
    
    // 绘制三角形2
    this.drawTriangle(ctx, 250, 150, 350, 150, 300, 100, '三角形 2', 2)
  }
  
  // 绘制单个三角形
  private drawTriangle(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, label: string, triangleIndex: number) {
    // 绘制三角形
    ctx.beginPath()
    ctx.moveTo(x1, y1)
    ctx.lineTo(x2, y2)
    ctx.lineTo(x3, y3)
    ctx.closePath()
    ctx.strokeStyle = '#333333'
    ctx.lineWidth = 2
    ctx.stroke()
    
    // 绘制标签
    ctx.font = '14px sans-serif'
    ctx.fillStyle = '#333333'
    ctx.fillText(label, x1 - 30, y1 - 10)
    
    // 绘制边长标签
    const sides = ['a', 'b', 'c']
    const points = [[x1, y1, x2, y2], [x2, y2, x3, y3], [x3, y3, x1, y1]]
    
    for (let i = 0; i < 3; i++) {
      const point = points[i]
      const x4 = point[0]
      const y4 = point[1]
      const x5 = point[2]
      const y5 = point[3]
      const midX = (x4 + x5) / 2
      const midY = (y4 + y5) / 2
      
      // 检查是否需要高亮
      const isHighlighted = this.highlightSides.includes(sides[i])
      
      if (isHighlighted) {
        // 高亮边
        ctx.beginPath()
        ctx.moveTo(x4, y4)
        ctx.lineTo(x5, y5)
        ctx.strokeStyle = '#4CAF50'
        ctx.lineWidth = 4
        ctx.stroke()
      }
      
      // 绘制边长标签
      ctx.font = '12px sans-serif'
      ctx.fillStyle = isHighlighted ? '#4CAF50' : '#666666'
      ctx.fillText(sides[i], midX, midY - 5)
    }
    
    // 绘制角度标签
    const angles = ['A', 'B', 'C']
    const anglePoints = [[x1, y1], [x2, y2], [x3, y3]]
    
    for (let i = 0; i < 3; i++) {
      const point = anglePoints[i]
      const x = point[0]
      const y = point[1]
      
      // 检查是否需要高亮
      const isHighlighted = this.highlightAngles.includes(angles[i])
      
      if (isHighlighted) {
        // 高亮角
        ctx.beginPath()
        ctx.arc(x, y, 10, 0, Math.PI * 2)
        ctx.strokeStyle = '#2196F3'
        ctx.lineWidth = 2
        ctx.stroke()
      }
      
      // 绘制角度标签
      ctx.font = '12px sans-serif'
      ctx.fillStyle = isHighlighted ? '#2196F3' : '#666666'
      ctx.fillText(angles[i], x - 5, y + 5)
    }
  }
  
  // 比较两个数值是否相等(考虑浮点数精度)
  private isEqual(a: number, b: number): boolean {
    return Math.abs(a - b) < 0.001
  }
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐