/** * * Calculate the glideslope given our current position/altitude and the position/elevation of * the target airport * * @param gpsParams where we are * @param dest what our destination is */ public void calcGlideSlope(GpsParams gpsParams, Destination dest) { // Show no vertical offset by default mDspOffset = 0; mBackColor = mColorOn; // If either of these objects are null, there is nothing // we can do if (dest == null || gpsParams == null) { mShow = false; return; } // Fetch the elevation of our destination. If we can't find it // then we don't want to display any vertical information double destElev = dest.getElevation(); if (destElev == -200) { mShow = false; return; } // Calculate our relative AGL compared to destination. If we are // lower then no display info double relativeAGL = gpsParams.getAltitude() - destElev; // Convert the destination distance to feet. double destDist = dest.getDistance(); double destInFeet = mConvertToFt * destDist; // Figure out our glide slope now based on our AGL height and distance mGlideSlope = Math.toDegrees(Math.atan(relativeAGL / destInFeet)); // Set the color of the glide slope background. According to the AIM, // if (mGlideSlope < (3 - BAR_DEGREES)) { mBackColor = mColorLow; } else if (mGlideSlope > (3 + BAR_DEGREES)) { mBackColor = mColorHigh; } // Calculate the vertical display offset of the indicator // Anything greater/equal to 3.7 pegs at the top // Anything less/equal to 2.3 pegs at the bottom // all others scale in between based upon instrument height double fullDeflection = mInstHeight / 2 - mBarHeight * 1.5; if (mGlideSlope >= 3.7) { mDspOffset = -(int) fullDeflection; } else if (mGlideSlope <= 2.3) { mDspOffset = (int) fullDeflection; } else { mDspOffset = -(int) ((((mGlideSlope - 3) / BAR_DEGREES)) * (fullDeflection / ((mBarCount - 1) / 2))); } mShow = true; }
/** * * Draw the instrument on the canvas given the current screen size This is called during the * screen refresh/repaint - be quick about it; no "new" calls. * * @param canvas What to draw upon * @param screenX Total width of the display canvas * @param screenY Total height of the display canvas * @param dest The target destination */ public void drawVNAV(Canvas canvas, float screenX, float screenY, Destination dest) { // If we have no destination set, then do not draw anything if (dest == null || (!mShow)) { mShow = false; return; } // If we are more than 30 miles from our target, then do not // draw anything double destDist = dest.getDistance(); if (destDist > APPROACH_DISTANCE) { mShow = false; return; } // Calculate the top position of the instrument mInstTop = (screenY - mInstHeight) / 2; // Now the left side mInstLeft = screenX - mInstWidth; // Right side of display // Draw the background mVNAVPaint.setColor(mBackColor); // Color mVNAVPaint.setAlpha(0x5F); // Make it see-thru mVNAVPaint.setStrokeWidth(mInstWidth); // How tall the inst is mVNAVPaint.setStyle(Paint.Style.STROKE); // Type of brush // Draw the background of the instrument. This is a vertical swipe top to bottom. canvas.drawLine(mInstLeft, mInstTop, mInstLeft, mInstTop + mInstHeight, mVNAVPaint); // Draw all of the horizontal bars mVNAVPaint.setColor(Color.WHITE); // white mVNAVPaint.setStrokeWidth(mBarHeight); // height of each bar for (int idx = 0; idx < mBarCount; idx++) { float extend = (idx == (int) (mBarCount / 2)) ? mInstWidth / 3 : 0; float barTop = mInstTop + mBarHeight * (float) 1.5 + idx * (mBarHeight + mBarSpace); canvas.drawLine( mInstLeft + mBarHeight - mInstWidth / 2, barTop, mInstLeft + mBarHeight + mBarWidth - mInstWidth / 2 + extend, barTop, mVNAVPaint); } // Now draw the needle indicator at the vertical center adjusted by the offset drawIndicator(canvas, screenY / 2 - mDspOffset); }