Android Open Source - lunatick Luna






From Project

Back to project page lunatick.

License

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.

Java Source Code

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




Java Source Code List

com.bellenir.lunatick.Info.java
com.bellenir.lunatick.LunaTick.java
com.bellenir.lunatick.Luna.java
com.bellenir.lunatick.Tick.java
com.bellenir.lunatick.Widget.java