@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // The view displays 90 degrees across its width so that one 90 degree // head rotation is equal to one full view cycle. float pixelsPerDegree = getWidth() / 90.0f; float degreesPerTick = 360.0f / mDirections.length; float centerX = getWidth() / 2.0f; float centerY = getHeight() / 2.0f; canvas.save(); canvas.translate(-mHeading * pixelsPerDegree + centerX, centerY); mPaint.setColor(Color.WHITE); // We draw two extra ticks/labels on each side of the view so that the // full range is visible even when the heading is approximately 0. for (int i = -2; i <= mDirections.length + 2; i++) { if (MathUtils.mod(i, 2) == 0) { // Draw a text label for the even indices. String direction = mDirections[MathUtils.mod(i, mDirections.length)]; mPaint.getTextBounds(direction, 0, direction.length(), mTextBounds); canvas.drawText( direction, i * degreesPerTick * pixelsPerDegree - mTextBounds.width() / 2, mTextBounds.height() / 2, mPaint); } else { // Draw a tick mark for the odd indices. canvas.drawLine( i * degreesPerTick * pixelsPerDegree, -TICK_HEIGHT / 2, i * degreesPerTick * pixelsPerDegree, TICK_HEIGHT / 2, mTickPaint); } } canvas.restore(); mPaint.setColor(NEEDLE_COLOR); drawNeedle(canvas, false); drawNeedle(canvas, true); }
/** * Converts the specified heading angle into an index between 0-15 that can be used to retrieve * the direction name for that heading (known as "boxing the compass", down to the half-wind * level). * * @param heading the heading angle * @return the index of the direction name for the angle */ public static int getHalfWindIndex(float heading) { float partitionSize = 360.0f / NUMBER_OF_HALF_WINDS; float displacedHeading = MathUtils.mod(heading + partitionSize / 2, 360.0f); return (int) (displacedHeading / partitionSize); }
/** * Sets the current heading in degrees and redraws the compass. If the angle is not between 0 and * 360, it is shifted to be in that range. * * @param degrees the current heading. */ public void setHeading(float degrees) { mHeading = MathUtils.mod(degrees, 360.0f); invalidate(); }