ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

鸿蒙 ArkTS 实战|一元一次方程计算器:ax+b=0 求解 + Canvas 直线图像 + 波点变动

鸿蒙 ArkTS 实战|一元一次方程计算器:ax+b=0 求解 + Canvas 直线图像 + 波点变动 一、设计思路一元一次方程是代数起点本页把一个方程做透①求解——输入 a、b由 ax b 0 反推 x −b/a②图像——用 Canvas 画坐标系与直线 y kx b③波点变动——一个亮色波点沿直线往返移动坐标与象限实时刷新把代数解变成看得见的点。三个功能共用一套 State输入即重算、重绘。二、状态与核心求解逻辑import{router}fromkit.ArkUI;interfacePixel{px:number;py:number;}EntryComponentstruct LinearEquation{StatecoeffA:number2;// 方程系数 aStatecoeffB:number-4;// 方程常数 bStatesolution:stringx 2.00;Stateslope:number1;// 直线斜率 kStateintercept:number1;// 直线截距 b// 波点动画状态StatedotX:number-8;// 波点当前横坐标StatedotY:number1;// 波点当前纵坐标 y kx bStatedotQuadrant:string第二象限;StatemovingRight:booleantrue;// 运动方向碰到边界反向privatetimer:number0;privatereadonlyxRange:number10;// x 显示范围 ±10privatereadonlyyRange:number6;// y 显示范围 ±6privatesettings:RenderingContextSettingsnewRenderingContextSettings(true);privatectx:CanvasRenderingContext2DnewCanvasRenderingContext2D(this.settings);// 解方程 ax b 0移项 系数化1privatesolve():void{constathis.coeffA;constbthis.coeffB;if(a0){this.solution(b0)?任意实数:无解;}else{this.solutionx (-b/a).toFixed(2);}}// 直线函数值privateyOf(x:number):number{returnthis.slope*xthis.intercept;}}三、波点变动动画setInterval 驱动aboutToAppear():void{this.solve();this.draw();// 波点变动每 30ms 步进一次x 每次 ±0.2this.timersetInterval((){this.tick();},30);}aboutToDisappear():void{clearInterval(this.timer);// 页面销毁必须清理定时器}// 波点步进沿直线平移碰到显示边界反向波点变动核心privatetick():void{letnxthis.dotX(this.movingRight?0.2:-0.2);if(nxthis.xRange){nxthis.xRange;this.movingRightfalse;}if(nx-this.xRange){nx-this.xRange;this.movingRighttrue;}this.dotXnx;this.dotYthis.yOf(nx);// y 由直线方程实时算出this.dotQuadrantthis.quadrantOf(nx,this.dotY);this.draw();// 每帧重绘}// 象限判定按坐标符号privatequadrantOf(x:number,y:number):string{if(x0y0)return第一象限;if(x0y0)return第二象限;if(x0y0)return第三象限;return第四象限;}四、Canvas 绘制网格 坐标轴 直线 波点// 世界坐标 → 画布像素画布中心即原点y 轴向上privatetoPixel(x:number,y:number,w:number,h:number):Pixel{return{px:w/2(x/this.xRange)*(w/2),py:h/2-(y/this.yRange)*(h/2)};}privatedraw():void{constctxthis.ctx;constwctx.width;consthctx.height;ctx.clearRect(0,0,w,h);// 网格x、y 方向各画 20 条浅色线ctx.strokeStyle#EEF1F6;ctx.lineWidth1;for(letgx-this.xRange1;gxthis.xRange;gx){constp1this.toPixel(gx,-this.yRange,w,h);constp2this.toPixel(gx,this.yRange,w,h);ctx.beginPath();ctx.moveTo(p1.px,p1.py);ctx.lineTo(p2.px,p2.py);ctx.stroke();}for(letgy-this.yRange1;gythis.yRange;gy){constp1this.toPixel(-this.xRange,gy,w,h);constp2this.toPixel(this.xRange,gy,w,h);ctx.beginPath();ctx.moveTo(p1.px,p1.py);ctx.lineTo(p2.px,p2.py);ctx.stroke();}// 坐标轴与标签constoriginthis.toPixel(0,0,w,h);ctx.strokeStyle#C7CDDA;ctx.lineWidth2;ctx.beginPath();ctx.moveTo(0,origin.py);ctx.lineTo(w,origin.py);ctx.stroke();ctx.beginPath();ctx.moveTo(origin.px,0);ctx.lineTo(origin.px,h);ctx.stroke();ctx.fillStyle#9CA3AF;ctx.font12px sans-serif;ctx.textAligncenter;ctx.fillText(x,w-14,origin.py-8);ctx.fillText(y,origin.px10,14);ctx.fillText(O,origin.px8,origin.py16);// 直线 y kx b取 x ±10 两端连线超出自动裁剪constlp1this.toPixel(-this.xRange,this.yOf(-this.xRange),w,h);constlp2this.toPixel(this.xRange,this.yOf(this.xRange),w,h);ctx.strokeStyle#4C7DFF;ctx.lineWidth3;ctx.beginPath();ctx.moveTo(lp1.px,lp1.py);ctx.lineTo(lp2.px,lp2.py);ctx.stroke();// 波点外圈光晕 实心圆 白描边constdpthis.toPixel(this.dotX,this.dotY,w,h);ctx.beginPath();ctx.arc(dp.px,dp.py,10,0,Math.PI*2);ctx.fillStylergba(16,185,129,0.25);ctx.fill();ctx.beginPath();ctx.arc(dp.px,dp.py,5,0,Math.PI*2);ctx.fillStyle#10B981;ctx.fill();ctx.strokeStyleColor.White;ctx.lineWidth2;ctx.stroke();}五、UI 组装波点数据面板 双输入区build(){Column(){// 顶部标题栏返回 标题略Scroll(){Column({space:14}){// 公式卡Text(ax b 0 → x −b/a).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#4C7DFF).width(100%).textAlign(TextAlign.Center)// 直线与波点Canvas(this.ctx).width(100%).height(240).onReady((){this.draw();})// 波点实时数据面板State 自动刷新无需手动 setStateRow({space:10}){Column({space:4}){Text(横坐标 x).fontSize(12).fontColor(#9CA3AF)Text(this.dotX.toFixed(1)).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#10B981)}.layoutWeight(1)Column({space:4}){Text(纵坐标 y).fontSize(12).fontColor(#9CA3AF)Text(this.dotY.toFixed(1)).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#10B981)}.layoutWeight(1)Column({space:4}){Text(所在象限).fontSize(12).fontColor(#9CA3AF)Text(this.dotQuadrant).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#4C7DFF)}.layoutWeight(1.4)}.width(100%).margin({top:4})// 方程求解输入区Row({space:10}){Text(a ).fontSize(14).fontColor(#111827)TextInput({text:this.coeffA.toString()}).width(80).height(36).type(InputType.Number).onChange((v:string){this.coeffANumber(v)||0;this.solve();// 改 a 立即重算解})Text(b ).fontSize(14).fontColor(#111827)TextInput({text:this.coeffB.toString()}).width(80).height(36).type(InputType.Number).onChange((v:string){this.coeffBNumber(v)||0;this.solve();})Blank()}.width(100%)// 直线参数输入区k、b 输入同构改后 this.draw() 重绘// 略与上同理}.padding(14)}.layoutWeight(1).scrollBar(BarState.Off)}.height(100%).width(100%).backgroundColor(#F4F6FA)}六、代码要点一帧一步setInterval(tick, 30)每次只挪0.2个单位形成平滑的波点变动aboutToDisappear里clearInterval防止泄漏。往返边界movingRight布尔状态碰到±xRange翻转波点往复扫过整条可见直线。坐标映射toPixel把数学坐标中心原点、y 向上转成画布像素左上原点、y 向下负号只出现在一处。声明式刷新波点坐标是State数据面板自动更新Canvas 需手动调draw()两种刷新模式配合。七、一元一次方程核心知识点要点内容定义只含一个未知数、未知数次数为 1、系数不为 0 的方程ax b 0a ≠ 0求解移项 → 系数化 1x −b/a特殊情况a 0 且 b 0任意实数a 0 且 b ≠ 0无解图像一次函数 y kx b 是一条直线k 斜率、b 与 y 轴交点性质波点沿直线运动时 y 恒等于 kx b任意时刻都满足方程易错移项要变号系数化 1 要除系数而不是减系数口诀一元一次解方程移项变号系数分k 正上升 k 负降b 是 y 轴相交点
返回列表