很多研究Robocode的 玩家都被其中的方向及坐標弄糊塗了。下面就跟著 Skyala.Li一起來揭開其中的奧妙。
前言:
很多研究Robocode的 玩家都被其中的方向及坐標弄糊塗了。下面就跟著 Skyala.Li一起來揭開其中的奧妙。
首先我們來看看一段英文的翻譯及說明:
heading - absolute angle in degrees with 0 facing up the screen, positive clockwise. 0 <= heading < 360.
bearing - relative angle to some object from your robot's heading, positive clockwise. -180 < bearing <= 180
heading:是機器人方向與屏幕正上方的角度差,方向在0到360之間.
bearing:是機器人的某個部件如雷達發現的目標與方向的角度差,順時針為 正角度在-180到180之間
看了這段文字大家可能還是不太明白,整個屏幕哪個是0度角,整個是坐標原 點呢? 順時針與逆時針的方向如何區分?
概念與平面圖:
在開始說明之前大家先得清楚幾個在Robocode中很重要的概念:
坐標系:Robocode整個坐標系都是戰場屏幕以左下角為原點
絕對方向系:Robocode中不管機器人在哪個方向都是以靜態戰場屏幕為參照 的絕對角度(也即大家說的Heading),正上方為0度角。也即不管是 Robot,Gun,Radar向北為0,向東為90,向南為180,向西為270。
相對方向系:相對方向是Robot,Gun,Radar以機器人的動態heading角度為參 照的角度差不再以整個靜態屏幕為參照了,叫它相對因為機器人的heading是隨 著機器人移動而不停的在改變,heaing只是個相對物體。
下圖很清楚的說明了坐標系統及絕對方向
哦似乎明白了一些,可頭腦中還有一些不是很清楚。我們來做個測試。測試 方法很簡單,寫兩個機器人,一個什麼一動不動坐在原點掃掃Gun並打印出自己的 Heading我們叫它Geny;另一個也不移動,只是Gun進行緩慢的轉動同時打印出自 己的Heading,Bearing,和Radar的 Heading,我們叫它GenyTrack1. (注:此處的 數據是double類型,沒有進行轉化我們近似的認識它為整數,具體的轉化方法和 更好測試方法我們會在以後的文章中給出):
代碼如下Geny.java
//Geny.java
package wind;
import robocode.*;
import java.io.*;
public class Geny extends Robot
{
public void run() {
ahead(100);
System.out.println("Heading "+getHeading());
while(true) {
turnGunRight(360);
}
}
}
GenyTrack1.java
//GenyTrack1.java
package wind;
import robocode.*;
public class GenyTrack1 extends Robot
{
public void run () {
while (true)
{
turnGunRight(5);
}
}
public void onScannedRobot(ScannedRobotEvent e)
{
System.out.println("getBearing "+e.getBearing ());
System.out.println("heading "+getHeading());
System.out.println("getRadarHeading() "+getRadarHeading());
turnGunRight(e.getBearing());
fire(3);
}
}
要想了解機器人的各個部件及說明請看文章:Robocode機器人解剖圖
絕對方向系Heading:
下面是剪切到的Geny和GenyTrack1在不同位置得到的數據圖.
圖一
圖一解:大家觀察機器人GenyTrack1的數據heading:64.421114…~ 64,說明 它正好坐落在屏幕絕對方向系64度的地方。也就是說GenyTrack1當前的Heading 方向為64度。
圖二
圖二解:大家觀察機器人GenyTrack1的數據heading:161.79…,說明它正前方 正好正對屏幕絕對方向系161度的地方。也就是說GenyTrack1當前的Heading方向 為161度。而我們的Geny正前方正對35度的地方。
大家對照著方向系一看我想一切就會明白的。是不是有點成就感了,不急, 後面還有。
相對方向系Bearing:
Bearing,Bearing 該死的Bearing,我想大家頭痛的就是它的。在此我們就 以機器人的雷達(Radar)為例來說明,源程序(GenyTrack1)中我們用到的是事 件:onScannedRobot(ScannedRobotEvent e) ,所以我們要用到的就是Radar的 Heading,其它相關的如Bullet,Gun的方法類似,有興趣的朋友可以自己測試一 下。
我們先把數據近似提出來如下表:
機器人 Heaing RadarHeading Bearing Geny 35 . . GenyTrack1 161 275 114
在此處機器人和Radar的Heading我想大家對照圖上的方向系及上面的絕對方 向體系說明應該明白了,只是要注意機器人哪是前哪是後:詳見Robocode機器人 解剖圖.
(Geny 的Heading在此處沒有用上,只是給大家參考一下)你看我們的 GenyTrack1前面正對著161角,雷達在屏幕276度角的地方發現了Geny機器人。所 以此處的Geny和GenyTrakc1相差的角度=|276-161|度(取絕對值,正負由轉動方 向決定),由於此時的Geny機器人正位於 GenyTrack1順時針方向上(GenyTrack1 的0,180之間),所以相對角度Bearing就是順時針方向(+114)度,(圖上每次數據 有一小點差是由於打印的數據及低級機器人完成所有代碼後才進行處理事件。不 是即時的。要即時處理涉及到高級機器人AdvanceRobot的一些特性)。
下面得到相對角度是為負的圖:原理同上。
圖三
機器人 Heaing RadarHeading Bearing Geny 35 . . GenyTrack1 57 238 -173
|238-57|,由於Geny處於GenyTrack1背後(-180,0)。為逆時針方向所以為負 。
時針略說:
順時針和逆時針是看另一機器人是在你的Heading角度的(0,180)還是(- 180,0)之間。
再這次提醒:Heading是個靜態角度,正上方總為0.不管是取Heading,還是 取方向
Bearing是個角度差值,是由參照的Heading和發現時的Heading的差值。
好了,方向的問題就說到這,這是Skyala.Li的理解,歡迎大家來討論。此處 沒有引用坐標系的詳細說明。請看: Robocode 基本原理之坐標系剖析