我正在为Android手机开发一个增强现实(AR)应用程序。我想以两个旋转轴的形式显示我的方向数据:一个位于屏幕顶部,以显示当前方位角(北,东,南,西),另一个在侧面显示高度/高程。我是Android编程的新手,因此我不确定如何在视觉上创建这些轴。

我的第一个想法是,我可以使用预定义的图像在撞到屏幕边缘时以某种方式包裹着(好像图像在旋转缸的外部)。从这里开始,将图像与我从传感器中获取的信息进行排列是一个简单的问题。

是否有某种方法可以包裹图像,以便可以以这种方式以虚拟平面旋转它们?有人可以建议更好地解决我的原始问题吗?

有帮助吗?

解决方案

我被挤压时间,所以我想出了一个硬编码的解决方案,该解决方案可能会扩展到更普遍的情况,而不会太多麻烦。要创建轴,我可以通过编程方式生成一堆路径对象,然后将它们绘制到我的画布上。然后,我只是根据我收集的方位角值来回翻译画布。

这是我用来生成方位角轴的类的副本:

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;
}   

}

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top