熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

Java新學法之Robocode基本原理之坐標鎖定(下)

2013-11-15 11:43:46  來源: JSP教程 

  至於Math類庫的使用我們就不詳細說明了讀者也可從下面的IBM Java專區鏈接中找到很多有關的知識也可參考一些Java類庫書籍說明當你設計高級Robocode機器人時你會發現Math類庫是你不可缺少的一部分知識此處我們只簡單的介紹正弦函數及余弦函數的使用
  
  Sin
  public static double sin(double a)
  
  Returns the trigonometric sine of an angle
  
  Parameters:
  
  a an angle in radians
  
  Returns:
  
  the sine of the argument
  
  Sin函數返回三角的正弦函數參數a是一個以double類型以弧度表示的角度值返回類型為double
  
  cos
  public static double cos(double a)
  
  Returns the trigonometric cosine of an angle
  
  Parameters:
  
  a an angle in radians
  
  Returns:
  
  the cosine of the argument
  
  Cos函數返回三角的余弦函數參數a是一個以double類型的弧度表示的角值返回類型為double
  
  有人會問為什麼不使用ScanndeRobot事件中的getRadarHeadingRadians()方法直接得到弧度你來看看Robocode中華聯盟iiley的一段說明
  
  public void onScannedRobot(ScannedRobotEvent event) {
  enemyX=Mathsin(UtilstandardMathDirRadians(getRadarHeadingRadians()))*eventgetDistance();
  enemyY=s(UtilstandardMathDirRadians(getRadarHeadingRadians()))*eventgetDistance();
  }
  
  看起來好像正確的但是你實踐一下會發現他很不准確為什麼呢?原因在於getRadarHeadingRadians()函數當你調用此函數的時候實際上雷達已經不在剛剛掃描到敵人的那個角度了他已經轉過了十幾度甚至更多雷達默認轉動速度是度/robocode單位時間實際上一般來說你用getRadarHeadingRadians()得到的值總是度的整數倍(一些情況除外比如說你用了turnRadarLeft()類似的語句以後)
  
  Robocode也遵循數學應用中的基本法則用兩種方法來表示方向的角度角度制和弧度制本文的代碼及以前文章中的代碼我們一直用的是角度制另外一種方法就是利用ScannedRobotEventgetBearingRadians()+robotgetHeadingRadians()得到敵人以弧度表示的方向這個方法在本文章中沒有說明了有興趣的朋友可以自己試試用Javautil 類庫來實現 也可參考文檔精確計算敵人的坐標大家也可比較兩種方法各自特點這將是個很有意思的過程
  
  移動鎖定
  當然即使是最簡單的機器人也不會坐在那一動不動等著你來消滅它會躲避你的進攻以及掃描當你向它原來坐標處開火說不定它已經跑得老遠了當然這一切都不是我們所希望看到的 我們的目的是要消滅它:不管他是移動或靜止的下面我們就結合方向系統與坐標系統來鎖定我們移動的目標創造一個我們自己的高級掃描機器人建議你在此處下載源代碼(resource)並看看演示效果再回到我們的文章中來顯示如圖
  
 

  
 

  

  
  對比一下上面的數據不管目標GenyMove在哪GenyRadar都能得到它精確的坐標是不是有一種成就感!是的敵人已經完全在我們的掌握之中即使它在移動中也無法擺脫我們雷達的掃描控制這裡只是很簡單舉了一些例子GenyMove在每一個時間周期(有關時間周期的說明見的Rock em sock em Robocode: Round )移動自己的位置並打印出移動後的坐標而GenyRadar掃描系統不停的掃描目標並一直追蹤同時打印出掃描到的GenyMove方位關鍵部分在我們的ScannedRobotEvent事件如列表
  
  列表:
  
  public void onScannedRobot( ScannedRobotEvent e )
  {
  
  double heading = egetBearing() +getHeading();
  
  double distance = egetDistance(); //求得距離
  
  double ager_bearing = MathtoRadians(heading % ); //角度轉為弧度
  
  double genyX = getX() + Mathsin(ager_bearing) * distance;
  
  double genyY = getY() + s(ager_bearing) * distance;
  
  outprintln(genyX:+ Mathround(genyX));
  
  outprintln(genyY:+ Mathround(genyY));
  
  if( heading >= )
  
  heading = heading ;
  
  if( heading < )
  
  heading = heading +;
  
  double bearing = getRadarHeading() heading;
  
  double radar_degree;
  
  boolean radar_direction;
  
  if( <= bearing && bearing <= 180 )
  
  {
  
  radar_direction = LEFT;
  
  }
  
  else if( bearing <= -180 )
  
  {
  
  radar_direction = LEFT;
  
  bearing = ( 360 + bearing );
  
  }
  
  else if( bearing < 0 )
  
  {
  
  radar_direction = RIGHT;
  
  bearing =( -bearing );
  
  }
  
  else
  
  {
  
  radar_direction = RIGHT;
  
  bearing = (360 - bearing);
  
  }
  
  radar_degree = bearing * 1.3 ; //加大每一時間周期(tick)的掃描范圍
  
  if( radar_direction == RIGHT )
  
  {
  
  setTurnRadarRight( radar_degree );
  
  execute();
  
  }
  
  else
  
  {
  
  setTurnRadarLeft( radar_degree );
  
  execute();
  
  }
  
  我們在代碼中首先求得GenyMove的絕對角度,然後用掃描時雷達的絕對角度減去目標GenyMove的角度求得兩者的角度差也即我們雷達要旋轉的角度。Tw.wiNgwIt.COM最後利用一個小技巧radar_degree = bearing * 1.3 使雷達在目標的范圍左右擺動以擴大雷達掃描區域.這樣不管目標往哪邊移動都在自己的雷達掃描區內。
  
  在此沒有進行很詳細的講解了,我想憑你學到的方向及坐標知識很快能明白個中原理並設計出自己的高級掃描機器人來。 聰明的你可能會高興的想,哈,我的炮管用相同的辦法鎖定目標,這樣敵人不就沒辦法跑了,被我追著打。答案是錯誤的,雷達的掃描是條長線能直接定位到目標上 ,它到目標的時間差幾乎為零,並且雷達的掃描范圍比炮管大且精確。而炮管每時間周期只有20度,它定位目標是依靠著子彈,只有子彈打中了目標,才能說炮管的計算坐標是精確的。但是由於子彈 到達目標位置時需要一定的時間差,子彈本身又有速度值(20-3*power),所以要想炮管鎖定目標並讓子彈擊中目標,我們還得經過精確的計算,並要預測目標可能的行動:是直線前進,還是做圓周運動,還是隨機運動等等。 這些都是我們要充分考慮的因素。是不是很有挑戰性!這一切都在Robocode的世界中等待著您的創造!
  
  三角函數基礎
  下面我們只是很簡單的介紹了一下與Robocode相關的三角函數知識,要想了解詳細的,大家可從家中高中代數與幾何書中得到這一切。
  
  1.角的概念
  在平面內,角可以看作一條射線繞著它的端點旋轉而成的圖形。如圖,一條射線由原來的位置OA,繞著它的端點O按逆時方向旋轉到另一位置OB,就形成角a.旋轉開始時的射線OA叫做角a的始邊,旋轉終止時的射線OB叫做角a的終邊,射線的端點O叫做角a的頂點。習慣上,我們把按逆時針方向旋轉而成的角叫做正角;按順時針方向旋轉而成的角叫做負角.所有與a終邊相同的角包括a在內,可以用式子表示:a+K*360度,對應到Robocode的方向系統中,只要我們以機器人的heading方向做射線,延長到與屏幕交點處的角度就是我們機器人的heading角度。
  
 

  2.直角三角函數
  在△ABC中,∠a為直角,我們把銳角A的對邊與斜邊的比叫做∠A的正弦,記作sina;銳角a的鄰邊與斜邊的比叫做∠a的余弦,記作cosa,即
  
  sina=對邊BC/斜邊AB
  
  cosa=鄰邊AC/斜邊AB
  

  3.單位圓和三角函數線
  半徑為1的圓叫做單位圓。設單位圓的圓心與坐標原點重合,則單位圓與x軸的交點分為別為A(1,0)、A′(-1,0),與y軸的交點分別為B(0,1)、B′(0,-1)。設角a的頂點在圓心O,始點與x軸的正半軸重合,終邊與單位圓相交於點P,過點P作PM垂直x軸於M,則由直角三角函數的定義可知:OM=cosa,MP=sina ,點P的坐標為(cosa,sina),即P(cosa,sina)。其中cosa=OM*1,sina=MP*1。Robocode中所有有關的坐標都可用這種方法求得。
  
  4.弧度制
  用度做單位來度量角的制度叫做角度制。數學和其他科學研究中常用另一種度量角的制度—弧度制。以角的頂點為圓心,以任意長的半徑作圓把這個角所對的弧長與半徑的比來衡量角的制度叫做弧度制.長度等於半徑的弧長叫1弧度。這段弧所對的圓心角的大小也是1弧度。通常單位“弧度”省略不寫。例:弧長為1.3325。單位就是弧度。由角度和弧度兩種單位之間的關系得到:2π弧度=360度,2/3π弧度=270度,π弧度=180度,1/2π弧度=90度,並可推出1弧度 = 360度/2π = 57°即 1弧度=角度*1
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19511.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.