Back to project page lunatick.
The source code is released under:
Copyright (c) 2014, a. bellenir All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1....
If you think the Android project lunatick listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.bellenir.lunatick; // w ww.jav a2 s . c o m //Bitmap, Canvas, Color, Paint, Rect, RectF import android.graphics.*; import android.content.Context; import java.util.Date; public class Luna { /* PHASE & CALCULATION float for phase, where 0 <= phase < 1. 0.00 = new moon 0.25 = first quarter 0.50 = full moon 0.75 = third quarter to calculate the phase for some date: ($0 = previous result) date - EPOCH = miliseconds since a known full moon $0 % LUNAR_MONTH = miliseconds into the lunar month $0 / LUNAR_MONTH = phase; convert miliseconds to fraction between 0 and 1 */ //date of a known new moon: jan 1. 2014 11:14am GMT. public static final long EPOCH = 1388574840000L; //length of a lunar month (29.53059 days in miliseconds) public static final long LUNAR_MONTH = 2551442976L; //todo: calculate radius dynamically or provide in dip private static final int RADIUS = 500; public static Bitmap getPhaseBitmap(){ return getPhaseBitmap(getCurrentPhase(), RADIUS); } public static Bitmap getPhaseBitmap(double p, int r){ int d = r * 2; Bitmap bmp = Bitmap.createBitmap(d, d, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bmp); drawMunPhase(c, p, r); drawPhasePercent(c, p, r/2); return bmp; } public static double getCurrentPhase(){ long now = (new Date()).getTime(); return ((double)((now - EPOCH) % LUNAR_MONTH)) / ((double)LUNAR_MONTH); } public static void drawMunPhase(Canvas c, double phase, int r){ Paint munLightPaint = new Paint(); munLightPaint.setColor(Color.WHITE); Paint munDarkPaint = new Paint(); munDarkPaint.setColor(Color.BLACK); int hch = c.getHeight()/2; int hcw = c.getWidth()/2; //mun's circle boundaries . cant assume canvas is dxd. should center. //top left: RectF circleBounds = new RectF(0, 0, d, d); RectF circleBounds = new RectF(hcw - r, hch - r, hcw + r, hch + r); //terminator will be along an ellipse with the same height, but narrower than the mun's circle //total width = 2*RADIUS*cos(phase); should be centered (center = (r,r)) int w = (int)(r*Math.abs(Math.cos(phase * 2 * Math.PI))); //use multiplier to create terminator bounds RectF ellipseBounds = new RectF(hcw-w, hch-r, hcw+w, hch+r); //draw circle of dark mun c.drawCircle(hcw, hch, r, munDarkPaint); if(phase <= 0.25){ //waxing crescent //fill right half fillHalf(c, circleBounds, RIGHT, munLightPaint); //and cover to terminator bounds with dark paint fillHalf(c, ellipseBounds, RIGHT, munDarkPaint); }else if(phase <= 0.5){ //waxing gibbus //fill right half entirely fillHalf(c, circleBounds, RIGHT, munLightPaint); //and left half to terminator bounds fillHalf(c, ellipseBounds, LEFT, munLightPaint); }else if(phase <= 0.75){ //waning gibbus //fill left half entirely fillHalf(c, circleBounds, LEFT, munLightPaint); //and right half to terminator bounds fillHalf(c, ellipseBounds, RIGHT, munLightPaint); }else{ //waning crescent //fill left half fillHalf(c, circleBounds, LEFT, munLightPaint); //and cover to terminator bounds with dark paint fillHalf(c, ellipseBounds, LEFT, munDarkPaint); } } public static void drawPhasePercent(Canvas c, double phase, int txtsize){ //find canvas center int hcw = c.getWidth()/2; int hch = c.getHeight()/2; Paint munTextPaint = new Paint(); munTextPaint.setColor(Color.WHITE); munTextPaint.setTextSize(txtsize); //another paint to draw shadow Paint shadowPaint = new Paint(); shadowPaint.setColor(Color.BLACK); shadowPaint.setTextSize(txtsize); shadowPaint.setStyle(Paint.Style.FILL_AND_STROKE); shadowPaint.setStrokeWidth(5); String strPhase = Integer.toString((int)(phase*100+0.5)); //android txt positioning is stupid. //this positioning centers txt //Rect txtBounds = new Rect(); //munTextPaint.getTextBounds(strPhase, 0, strPhase.length(), txtBounds); //half text width/height //int htw = (txtBounds.right-txtBounds.left) / 2; //int hth = (txtBounds.bottom-txtBounds.top) / 2; //c.drawText(strPhase, hcw-txtBounds.left-htw, hch-txtBounds.top-hth, shadowPaint); //c.drawText(strPhase, hcw-txtBounds.left-htw, hch-txtBounds.top-hth, munTextPaint); //this centers if you dont want to center vertically munTextPaint.setTextAlign(Paint.Align.CENTER); shadowPaint.setTextAlign(Paint.Align.CENTER); //position phase so base is halfway between center and top. c.drawText(strPhase, hcw, hch/2, shadowPaint); c.drawText(strPhase, hcw, hch/2, munTextPaint); } private static final int LEFT = 1; private static final int RIGHT = -1; //fill half of an oval bound by rect private static void fillHalf(Canvas c, RectF rect, int half, Paint paint){ c.drawArc(rect, 90*half, 180, true, paint); } }