使用Math.toDegrees时代码循环仅执行一次的问题排查
问题排查与修复
首先,你犯了一个常见的角度/弧度转换错误:Math.cos() 和 Math.sin() 方法要求传入的参数是弧度值,但你用了 Math.toDegrees(40),这是把40弧度转换成角度值,完全搞反了转换方向。
错误原因详解
Math.toDegrees(rad) 的作用是将弧度值转为角度值,而你需要的是把40度这个角度值转为弧度值,正确的方法应该是 Math.toRadians(40)。
当你错误地使用 Math.toDegrees(40) 时,得到的是≈2291.83°这个角度数值,然后把它作为弧度参数传给cos/sin,相当于计算 cos(2291.83弧度) 和 sin(2291.83弧度)。这个超大的弧度值经过圆周取模后,对应的cos值为负数,sin值很小,导致:
x计算结果为负数(因为v0、t都是正数,cos值为负)y计算结果会快速变为负数(sin值的正向推力不足以抵消重力项的向下拉力)
这种异常的坐标计算会触发你代码里的终止条件,导致循环提前结束。
修复后的代码
把计算x和y的两行改成用Math.toRadians(40),同时我把硬编码的40替换成了你定义的变量a,让代码更易维护:
Scanner sc=new Scanner(System.in); double g=8.86,a=40; // a=角度 double v0,x,y,t; boolean bulletInFlight = true; boolean hitTarget = false; System.out.println("191RDB107 Vladislavs Fedotovs"); System.out.println("While operators,07,Urans"); System.out.print("v0="); if (sc.hasNextDouble()) v0 = sc.nextDouble(); else { System.out.println("input-output error"); sc.close(); return; } sc.close(); System.out.println("result:"); System.out.println("t \t x \t y"); t = 0.1; while(bulletInFlight) { x =v0*t*Math.cos(Math.toRadians(a)); // 正确转换角度为弧度 y =v0*t*Math.sin(Math.toRadians(a))-(g*Math.pow(t, 2))/2; System.out.printf("%3.2f\t%7.3f\t%7.3f\n", t, x, y); if (x >= 12 && x <= 17 && y <=-2 && y >=-4) // 红色目标 { bulletInFlight = false; hitTarget = true; t+=0.05; }else if ((x>= 0 && x<=10 && y<0)|| (x>10 && x<12 && y<=-4) ||(x>10 && y<=-4)) // 绿色草地 { bulletInFlight = false; t+=0.05; }else t+=0.05; } if (hitTarget) System.out.println("the target was destroyed"); else System.out.println("shot off the target");
为什么原代码循环只执行一次?
当你用Math.toDegrees(40)时,x会变成负数,同时如果输入的v0较小,第一次计算的y会快速变为负数。虽然你的草地条件没有直接判断x<0的情况,但异常的坐标会导致代码逻辑提前触发终止(比如部分边界条件的误判),最终让循环只运行一次。修复角度转换后,弹道计算会回到正常逻辑,循环也会按照预期执行。
内容的提问来源于stack exchange,提问作者Vlad Fedotov
相关产品推荐
相关产品推荐

