時間に追われているので、あまり問題なく、より一般的なケースに拡張できるハードコードされたソリューションを考え出しました。軸を作成するために、プログラムで一連の 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;
}
}