1

我正在研究Android手機的增強現實(AR)應用程序。我想以兩個旋轉軸的形式顯示我的方向數據:一個位於屏幕頂部以顯示當前方位(北,東,南,西),另一個顯示海拔/仰角。我是Android編程的新手,所以我不確定如何直觀地創建這些軸。Android AR羅盤顯示器

我的第一個想法是,我可以使用預定義的圖像,在按屏幕邊緣時以某種方式迴繞(就像圖像位於旋轉圓柱體的外側)。從這裏開始,將影像與我從傳感器中獲取的信息排列起來會很簡單。

有沒有某種方式來包裝圖像,以便它們可以以這種方式在虛擬平面中旋轉?任何人都可以提出更好的解決方案來解決我最初的問題嗎

回答

0

我緊迫的時間,所以我想出了一個硬編碼的解決方案,可能會擴展到更普遍的情況下,沒有太多的麻煩。爲了創建軸,我以編程方式生成一堆Path對象,然後將它們繪製到我的畫布上。然後,我只是根據我收集的方位角值來回轉換畫布。

下面是類的副本我用於生成方位軸:

class AzimuthOverlay extends View { 

// Values hardcoded for fullscreen landscape 
// Width = 800 pixels 

int tickPixels = 40; // Number of pixels between tick marks 
final int MAJORTICKS = 36; 
final int MINORTICKS = 36; 

// Need additional 10 for proper wrapping 
final int TOTALOBJECTS = MAJORTICKS + MINORTICKS + 10; 

public double mAzimuth; // Set externally by a SensorEventListener class 

private Paint ticPaint = new Paint(); 
private Paint numPaint = new Paint(); 
private ArrayList<Path> axis = new ArrayList<Path>(TOTALOBJECTS); 

public AzimuthOverlay(Context context) { 
    super(context); 

    ticPaint.setAntiAlias(true); 
    ticPaint.setColor(Color.GREEN); 
    ticPaint.setStyle(Paint.Style.FILL); 

    numPaint.setColor(Color.GREEN); 
    numPaint.setStyle(Paint.Style.STROKE); 
    numPaint.setStrokeWidth(2); 

    // Extend to the left of the screen 
    for (int i = -10; i < 0; i++) { 
     if (i % 2 == 0) { 
      axis.add(getMajorTick(i * tickPixels)); 
     } 
     else { 
      axis.add(getNumber(360 + 5*i, i * tickPixels)); 
     } 
    } 

    // Create axis (numbers on minor ticks) 
    for (int i = 0; i < TOTALOBJECTS; i++) { 
     if (i % 2 == 0) { 
      axis.add(getMajorTick(i * tickPixels)); 
     } 
     else { 
      axis.add(getNumber((5*i)%360, i * tickPixels)); 
     } 
    } 


} 

@Override 
protected void onDraw(Canvas canvas) { 

    canvas.translate((int)-mAzimuth * 8, 0); // 8 pixels per degree 

    boolean toggle = true; // Alternate between ticks and numbers 
    for (Path p : axis) { 
     if (toggle) { 
      canvas.drawPath(p, ticPaint); 
     } 
     else { 
      canvas.drawPath(p, numPaint); 
     } 
     toggle = (toggle == false) ? true : false; 
    } 

    super.onDraw(canvas); 
} 

// Create big tick marks as Path object 
private Path getMajorTick(int offset) { 
    Path mypath = new Path(); 

    mypath.moveTo(-2 + offset, 0); 
    mypath.lineTo(-2 + offset, 20); 
    mypath.lineTo(2 + offset, 20); 
    mypath.lineTo(2 + offset, 0); 
    mypath.close(); 

    return mypath; 
} 

// Create small tick marks as Path object 
private Path getMinorTick(int offset) { 
    Path mypath = new Path(); 

    mypath.moveTo(-2 + offset, 0); 
    mypath.lineTo(-2 + offset, 10); 
    mypath.lineTo(2 + offset, 10); 
    mypath.lineTo(2 + offset, 0); 
    mypath.close(); 

    return mypath; 
} 

// Create individual digits as Path object 
private Path getDigit(int digit, int offset) { 
    Path mypath = new Path(); 

    final int lx = -6; 
    final int mx = 0; 
    final int rx = 6; 
    final int ty = 0; 
    final int my = 6; 
    final int by = 12; 

    final int doffset = 2; 

    switch(digit) { 
    case 0: 
     mypath.moveTo(lx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     mypath.lineTo(lx + offset, by + doffset); 
     mypath.close(); 
     break; 
    case 1: 
     mypath.moveTo(lx + offset, ty + doffset); 
     mypath.lineTo(mx + offset, ty + doffset); 
     mypath.lineTo(mx + offset, by + doffset); 
     mypath.lineTo(lx + offset, by + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     break; 
    case 2: 
     mypath.moveTo(lx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, my + doffset); 
     mypath.lineTo(lx + offset, my + doffset); 
     mypath.lineTo(lx + offset, by + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     break; 
    case 3: 
     mypath.moveTo(lx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     mypath.lineTo(lx + offset, by + doffset); 
     mypath.moveTo(lx + offset, my + doffset); 
     mypath.lineTo(rx + offset, my + doffset); 
     break; 
    case 4: 
     mypath.moveTo(lx + offset, ty + doffset); 
     mypath.lineTo(lx + offset, my + doffset); 
     mypath.lineTo(rx + offset, my + doffset); 
     mypath.lineTo(rx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     break; 
    case 5: 
     mypath.moveTo(rx + offset, ty + doffset); 
     mypath.lineTo(lx + offset, ty + doffset); 
     mypath.lineTo(lx + offset, my + doffset); 
     mypath.lineTo(rx + offset, my + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     mypath.lineTo(lx + offset, by + doffset); 
     break; 
    case 6: 
     mypath.moveTo(lx + offset, ty + doffset); 
     mypath.lineTo(lx + offset, by + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     mypath.lineTo(rx + offset, my + doffset); 
     mypath.lineTo(lx + offset, my + doffset); 
     break; 
    case 7: 
     mypath.moveTo(lx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     break; 
    case 8: 
     mypath.moveTo(lx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, ty + doffset); 
     mypath.lineTo(rx + offset, by + doffset); 
     mypath.lineTo(lx + offset, by + doffset); 
     mypath.lineTo(lx + offset, ty + doffset); 
     mypath.moveTo(lx + offset, my + doffset); 
     mypath.lineTo(rx + offset, my + doffset); 
     break; 
    case 9: 
     mypath.moveTo(rx + offset, by + doffset); 
     mypath.lineTo(rx + offset, ty + doffset); 
     mypath.lineTo(lx + offset, ty + doffset); 
     mypath.lineTo(lx + offset, my + doffset); 
     mypath.lineTo(rx + offset, my + doffset); 
     break; 
    } 

    return mypath; 
} 

// Create a number up to 3 digits as a Path object 
private Path getNumber(int number, int offset) { 
    Path mypath = new Path(); 

    final int digitoffset = 7; 

    int digit; 
    int temp; 
    if (number > 99) { // 3-digit number 
     digit = number/100; 
     mypath = getDigit(digit, offset - 2*digitoffset); 
     temp = (number % 100); 
     digit = temp/10; 
     mypath.addPath(getDigit(digit, offset)); 
     digit = temp % 10; 
     mypath.addPath(getDigit(digit, offset + 2*digitoffset)); 
    } 
    else if (number > 9) { // 2-digit number 
     digit = number/10; 
     mypath = getDigit(digit, offset-digitoffset); 
     mypath.addPath(getDigit(number % 10, offset+digitoffset)); 
    } 
    else { // 1-digit number 
     mypath = getDigit(number, offset); 
    } 

    return mypath; 
} 

protected void setAzimuth(double azimuth) { 
    mAzimuth = azimuth; 
} 

}