-
Notifications
You must be signed in to change notification settings - Fork 0
Chaance Graves Project 3
This app will track the position of the Moon via a 3D rendering and would be able to update information to the User such as (Ecliptic Latitude and Longitude, Phase, and distance in km). A Javascript based program was written in conjuction with obtaining the aforementionded values. From there it will be able to allow the user to open the camera screen to get an accurate representation of the location of the moon basesd's on the calculator's results. This app would be useful for any astronomy enthusiast or anybody wanting to get a sense of where the Moon can be agorithmatically.
- Augmented Reality with Camera API and OpenGL ES2.
- WebView application.
- GPS location of the device.
- Orientation sensor API.
Below is the classes used for CameraView and CameraProjectActivity. These classes in particualar were responsible for handling the the Surface view rendering of the Sphere when the camera is open.
package com.test;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class CameraView extends SurfaceView implements Callback {
private Camera camera;
public CameraView( Context context ) {
super( context );
// We're implementing the Callback interface and want to get notified
// about certain surface events.
getHolder().addCallback( this );
// We're changing the surface to a PUSH surface, meaning we're receiving
// all buffer data from another component - the camera, in this case.
getHolder().setType( SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS );
}
public void surfaceCreated( SurfaceHolder holder ) {
// Once the surface is created, simply open a handle to the camera hardware.
camera = Camera.open();
}
public void surfaceChanged( SurfaceHolder holder, int format, int width, int height ) {
// This method is called when the surface changes, e.g. when it's size is set.
// We use the opportunity to initialize the camera preview display dimensions.
Camera.Parameters p = camera.getParameters();
p.setPreviewSize( width, height );
camera.setParameters( p );
// We also assign the preview display to this surface...
try {
camera.setPreviewDisplay( holder );
} catch( IOException e ) {
e.printStackTrace();
}
// ...and start previewing. From now on, the camera keeps pushing preview
// images to the surface.
camera.startPreview();
}
public void surfaceDestroyed( SurfaceHolder holder ) {
// Once the surface gets destroyed, we stop the preview mode and release
// the whole camera since we no longer need it.
camera.stopPreview();
camera.release();
camera = null;
}
}package com.test;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;
import android.content.Intent;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.content.Context;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class CameraProjectActivity extends Activity{
/** Called when the activity is first created. */
//@Override
private TextView text, text1, text2,text3, text4, text5;
public void onCreate( Bundle savedInstanceState ) {
// Next, we disable the application's title bar...
requestWindowFeature( Window.FEATURE_NO_TITLE );
// ...and the notification bar. That way, we can use the full screen.
getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN );
super.onCreate(savedInstanceState);
setContentView(R.layout.cameraview);
// Now let's create an OpenGL surface.
GLSurfaceView glView = new GLSurfaceView( this );
// To see the camera preview, the OpenGL surface has to be created translucently.
// See link above.
glView.setEGLConfigChooser( 8, 8, 8, 8, 16, 0 );
glView.getHolder().setFormat( PixelFormat.TRANSLUCENT );
// The renderer will be implemented in a separate class, GLView, which I'll show next.
glView.setRenderer( new GLClearRenderer() );
// Now set this as the main view.
setContentView( glView );
// Now also create a view which contains the camera preview...
CameraView cameraView = new CameraView( this );
// ...and add it, wrapping the full screen size.
addContentView( cameraView, new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT ) );
// You can use a Framelayout to hold the surfaceview
FrameLayout frameLayout = new FrameLayout(this);
frameLayout.addView(glView);
// Here we declare the parameters to be seen on the screen with the 3D rendered model.
//text = (TextView) findViewById(R.id.distance);
//text1 = (TextView) findViewById(R.id.ecliptic_lat);
//text2 = (TextView) findViewById(R.id.ecliptic_long);
//text3 = (TextView) findViewById(R.id.distance);
//text4 = (TextView) findViewById(R.id.distance);
//text5 = (TextView) findViewById(R.id.distance);
// Then create a layout to hold everything, for example a RelativeLayout
RelativeLayout relativeLayout = new RelativeLayout(this);
relativeLayout.addView(frameLayout);
relativeLayout.addView(text); // show the distance in km
relativeLayout.addView(text1); // show the Ecliptic latitude of the moon.
relativeLayout.addView(text2); // show the Ecliptic longitude of the moon.
//relativeLayout.addView(text3); // Yaw?
//relativeLayout.addView(text4); // Pitch?
//relativeLayout.addView(text5); // Roll?
}
public void openCamera(View view){
Intent intent = new Intent(this, CameraProjectActivity.class);
}The sphere to be displayed on the screen was created with it's own java class with OpenGL seen below.
package com.test;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by Chaance on 4/21/2016.
*/
public class Sphere {
public void draw(GL10 gl) {
float angleA, angleB;
float cos, sin;
float r1, r2;
float h1, h2;
float step = 10.0f;
float[][] v = new float[32][3];
ByteBuffer vbb;
FloatBuffer vBuf;
vbb = ByteBuffer.allocateDirect(v.length * v[0].length * 4);
vbb.order(ByteOrder.nativeOrder());
vBuf = vbb.asFloatBuffer();
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
for (angleA = -90.0f; angleA <90.0f; angleA += step) {
int n = 0;
r1 = (float)Math.cos(angleA * Math.PI / 180.0);
r2 = (float)Math.cos((angleA + step) * Math.PI / 180.0);
h1 = (float)Math.sin(angleA * Math.PI / 180.0);
h2 = (float)Math.sin((angleA + step) * Math.PI / 180.0);
// Fixed latitude, 360 degrees rotation to traverse a weft
for (angleB = 0.0f; angleB <= 360.0f; angleB += step) {
cos = (float)Math.cos(angleB * Math.PI / 180.0);
sin = -(float)Math.sin(angleB * Math.PI / 180.0);
v[n][0] = (r2 * cos);
v[n][1] = (h2);
v[n][2] = (r2 * sin);
v[n + 1][0] = (r1 * cos);
v[n + 1][1] = (h1);
v[n + 1][2] = (r1 * sin);
vBuf.put(v[n]);
vBuf.put(v[n + 1]);
n += 2;
if(n>31){
vBuf.position(0);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuf);
gl.glNormalPointer(GL10.GL_FLOAT, 0, vBuf);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, n);
n = 0;
angleB -= step;
}
}
vBuf.position(0);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuf);
gl.glNormalPointer(GL10.GL_FLOAT, 0, vBuf);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, n);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}In terms of the WebView development of the project, this WebView was used to display the JavaScript calculator program once the button is clicked by the user.
package com.test;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
/**
* Created by Chaance on 4/29/2016.
*/
public class WebViewActivity extends Activity {
private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
webView = (WebView) findViewById(R.id.webview);
String myHTMLString = "\n" +
"<html>\n" +
"<head>\n" +
"<title>Lunarfinder Calculator</title>\n" +
"<link rel=\"stylesheet\" type=\"text/css\" href=\"../standard.css\">\n" +
"<SCRIPT language=JavaScript SRC=\"../feedback.js\"></SCRIPT>\n" +
"\n" +
"<script language=JavaScript>\n" +
"<!-- hide\n" +
"\n" +
"var n0 = parseInt( \"0\" );\n" +
"var f0 = parseFloat( \"0.0\" );\n" +
"var AG = f0; // Moon's age\n" +
"var DI = f0; // Moon's distance in earth radii\n" +
"var LA = f0; // Moon's ecliptic latitude\n" +
"var LO = f0; // Moon's ecliptic longitude\n" +
"var Phase = \" \";\n" +
"var Zodiac = \" \";\n" +
"\n" +
"function initialize()\n" +
"{\n" +
" var d = new Date();\n" +
"\n" +
" document.calc.year.value = d.getFullYear();\n" +
" document.calc.month.value = d.getMonth() + 1;\n" +
" document.calc.day.value = d.getDate();\n" +
"}\n" +
"\n" +
"function calculate()\n" +
"{\n" +
" var year = parseInt( document.calc.year.value, 10 ); \n" +
" var month = parseInt( document.calc.month.value, 10 ); \n" +
" var day = parseInt( document.calc.day.value, 10 );\n" +
"\n" +
" if( !isdayofmonth( year, month, day ) )\n" +
" {\n" +
" alert( \"Invalid date\" );\n" +
" return;\n" +
" }\n" +
"\n" +
" moon_posit( year, month, day );\n" +
" document.calc.age.value = round2( AG );\n" +
" document.calc.dst.value = round2( DI );\n" +
" document.calc.faz.value = Phase;\n" +
" document.calc.lat.value = round2( LA );\n" +
" document.calc.lon.value = round2( LO );\n" +
" document.calc.sgn.value = Zodiac;\n" +
"}\n" +
"\n" +
"var n28 = parseInt( \"28\" );\n" +
"var n30 = parseInt( \"30\" );\n" +
"var n31 = parseInt( \"31\" );\n" +
"var dim = new Array( n31, n28, n31, n30, n31, n30, n31, n31, n30, n31, n30, n31 );\n" +
"\n" +
"function isdayofmonth( y, m, d )\n" +
"{\n" +
" if( m != 2 )\n" +
" {\n" +
" if( 1 <= d && d <= dim[m-1] )\n" +
" return true;\n" +
" else\n" +
" return false;\n" +
" }\n" +
"\n" +
" var feb = dim[1];\n" +
" \n" +
" if( isleapyear( y ) )\n" +
" feb += 1; // is leap year\n" +
"\n" +
" if( 1 <= d && d <= feb )\n" +
" return true;\n" +
"\n" +
" return false; \n" +
"}\n" +
"\n" +
"function isleapyear( y )\n" +
"{\n" +
" var x = Math.floor( y - 4*Math.floor( y/4 ) );\n" +
" var w = Math.floor( y - 100*Math.floor( y/100 ) );\n" +
" var z = Math.floor( y - 400*Math.floor( y/400 ) );\n" +
"\n" +
" if( x == 0 ) // possible leap year\n" +
" {\n" +
" if( w == 0 && z != 0 )\n" +
" return false; // not leap year\n" +
" else\n" +
" return true; // is leap year\n" +
" }\n" +
"\n" +
" return false;\n" +
"}\n" +
"\n" +
"function backup( n )\n" +
"{\n" +
" var year = parseInt( document.calc.year.value, 10 );\n" +
" var month = parseInt( document.calc.month.value, 10 );\n" +
" var day = parseInt( document.calc.day.value, 10 );\n" +
"\n" +
" switch( n )\n" +
" {\n" +
" case 1:\n" +
" document.calc.year.value = year - 1;\n" +
" calculate();\n" +
" break;\n" +
" case 2:\n" +
" if( month < 2 )\n" +
" {\n" +
" document.calc.month.value = 12;\n" +
" document.calc.year.value = year - 1;\n" +
" }\n" +
" else\n" +
" document.calc.month.value = month - 1;\n" +
" calculate();\n" +
" break;\n" +
" case 3:\n" +
" if( day < 2 )\n" +
" {\n" +
" if( month < 2 )\n" +
" {\n" +
" document.calc.month.value = 12;\n" +
" document.calc.year.value = year - 1;\n" +
" }\n" +
" else\n" +
" document.calc.month.value = month - 1;\n" +
" \n" +
" month = parseInt( document.calc.month.value, 10 );\n" +
" if( month == 2 && isleapyear( year ) )\n" +
" document.calc.day.value = 29;\n" +
" else \n" +
" document.calc.day.value = dim[month-1];\n" +
" }\n" +
" else\n" +
" document.calc.day.value = day - 1;\n" +
" calculate();\n" +
" break;\n" +
" }\n" +
"}\n" +
"\n" +
"function advance( n )\n" +
"{\n" +
" var year = parseInt( document.calc.year.value, 10 );\n" +
" var month = parseInt( document.calc.month.value, 10 );\n" +
" var day = parseInt( document.calc.day.value, 10 );\n" +
"\n" +
" switch( n )\n" +
" {\n" +
" case 1:\n" +
" document.calc.year.value = year + 1;\n" +
" calculate();\n" +
" break;\n" +
" case 2:\n" +
" if( month < 12 )\n" +
" document.calc.month.value = month + 1;\n" +
" else\n" +
" {\n" +
" document.calc.month.value = 1;\n" +
" document.calc.year.value = year + 1;\n" +
" }\n" +
" calculate();\n" +
" break;\n" +
" case 3:\n" +
" if( isdayofmonth( year, month, day + 1 ) )\n" +
" document.calc.day.value = day + 1;\n" +
" else\n" +
" {\n" +
" if( month < 12 )\n" +
" document.calc.month.value = month + 1;\n" +
" else\n" +
" {\n" +
" document.calc.month.value = 1;\n" +
" document.calc.year.value = year + 1;\n" +
" }\n" +
"\n" +
" document.calc.day.value = 1;\n" +
" }\n" +
" calculate();\n" +
" break;\n" +
" }\n" +
"}\n" +
"\n" +
"// compute moon position and phase\n" +
"function moon_posit( Y, M, D )\n" +
"{\n" +
" var YY = n0;\n" +
" var MM = n0;\n" +
" var K1 = n0; \n" +
" var K2 = n0; \n" +
" var K3 = n0;\n" +
" var JD = n0;\n" +
" var IP = f0;\n" +
" var DP = f0;\n" +
" var NP = f0;\n" +
" var RP = f0;\n" +
" \n" +
" // calculate the Julian date at 12h UT\n" +
" YY = Y - Math.floor( ( 12 - M ) / 10 ); \n" +
" MM = M + 9; \n" +
" if( MM >= 12 ) MM = MM - 12;\n" +
" \n" +
" K1 = Math.floor( 365.25 * ( YY + 4712 ) );\n" +
" K2 = Math.floor( 30.6 * MM + 0.5 );\n" +
" K3 = Math.floor( Math.floor( ( YY / 100 ) + 49 ) * 0.75 ) - 38;\n" +
" \n" +
" JD = K1 + K2 + D + 59; // for dates in Julian calendar\n" +
" if( JD > 2299160 ) JD = JD - K3; // for Gregorian calendar\n" +
" \n" +
" // calculate moon's age in days\n" +
" IP = normalize( ( JD - 2451550.1 ) / 29.530588853 );\n" +
" AG = IP*29.53;\n" +
" \n" +
" if( AG < 1.84566 ) Phase = \"NEW\";\n" +
" else if( AG < 5.53699 ) Phase = \"Evening crescent\";\n" +
" else if( AG < 9.22831 ) Phase = \"First quarter\";\n" +
" else if( AG < 12.91963 ) Phase = \"Waxing gibbous\";\n" +
" else if( AG < 16.61096 ) Phase = \"FULL\";\n" +
" else if( AG < 20.30228 ) Phase = \"Waning gibbous\";\n" +
" else if( AG < 23.99361 ) Phase = \"Last quarter\";\n" +
" else if( AG < 27.68493 ) Phase = \"Morning crescent\";\n" +
" else Phase = \"NEW\";\n" +
"\n" +
" IP = IP*2*Math.PI; // Convert phase to radians\n" +
"\n" +
" // calculate moon's distance\n" +
" DP = 2*Math.PI*normalize( ( JD - 2451562.2 ) / 27.55454988 );\n" +
" DI = 60.4 - 3.3*Math.cos( DP ) - 0.6*Math.cos( 2*IP - DP ) - 0.5*Math.cos( 2*IP );\n" +
"\n" +
" // calculate moon's ecliptic latitude\n" +
" NP = 2*Math.PI*normalize( ( JD - 2451565.2 ) / 27.212220817 );\n" +
" LA = 5.1*Math.sin( NP );\n" +
"\n" +
" // calculate moon's ecliptic longitude\n" +
" RP = normalize( ( JD - 2451555.8 ) / 27.321582241 );\n" +
" LO = 360*RP + 6.3*Math.sin( DP ) + 1.3*Math.sin( 2*IP - DP ) + 0.7*Math.sin( 2*IP );\n" +
"\n" +
" if( LO < 33.18 ) Zodiac = \"Pisces\";\n" +
" else if( LO < 51.16 ) Zodiac = \"Aries\";\n" +
" else if( LO < 93.44 ) Zodiac = \"Taurus\";\n" +
" else if( LO < 119.48 ) Zodiac = \"Gemini\";\n" +
" else if( LO < 135.30 ) Zodiac = \"Cancer\";\n" +
" else if( LO < 173.34 ) Zodiac = \"Leo\";\n" +
" else if( LO < 224.17 ) Zodiac = \"Virgo\";\n" +
" else if( LO < 242.57 ) Zodiac = \"Libra\";\n" +
" else if( LO < 271.26 ) Zodiac = \"Scorpio\";\n" +
" else if( LO < 302.49 ) Zodiac = \"Sagittarius\";\n" +
" else if( LO < 311.72 ) Zodiac = \"Capricorn\";\n" +
" else if( LO < 348.58 ) Zodiac = \"Aquarius\";\n" +
" else Zodiac = \"Pisces\";\n" +
"\n" +
" // so longitude is not greater than 360!\n" +
" if ( LO > 360 ) LO = LO - 360;\n" +
"}\n" +
"\n" +
"// round to 2 decimal places \n" +
"function round2( x )\n" +
"{\n" +
" return ( Math.round( 100*x )/100.0 );\n" +
"}\n" +
" \n" +
"// normalize values to range 0...1 \n" +
"function normalize( v )\n" +
"{\n" +
" v = v - Math.floor( v ); \n" +
" if( v < 0 )\n" +
" v = v + 1;\n" +
" \n" +
" return v;\n" +
"}\n" +
"\n" +
"// clear input\n" +
"function allclear()\n" +
"{\n" +
" document.calc.year.value='0';\n" +
" document.calc.month.value='0';\n" +
" document.calc.day.value='0';\n" +
"}\n" +
"\n" +
"function Moondata(distance, ecliptic_latitude, ecliptic_longitude, Moon_phase) {\n" +
"this distance = distance;\n" +
"this ecliptic_latitude = ecliptic_latitude;\n" +
"this ecliptic_longitude = ecliptic_longitude;\n" +
"this Moon_phase = Moon_phase;\n" +
"}\n" +
"// unhide -->\n" +
"</script>\n" +
"\n" +
"</head>\n" +
"<body bgcolor=\"maroon\" text=\"white\" onLoad=initialize()>\n" +
"\n" +
"\n" +
"<h2>Lunarfinder Calculator</h2>\n" +
"\n" +
"<h4>ECEN 489\n" +
"\tProject 3</h4>\n" +
"\n" +
"<center>\n" +
"<form name=\"calc\">\n" +
"<table>\n" +
"<tr>\n" +
"<td><input type=\"button\" VALUE=\"<<\" onClick=\"backup( 1 )\">\n" +
"<td align=right>year \n" +
"<td><input type=\"text\" value=\"0\" NAME=\"year\" size=\"5\" maxlength=\"30\">\n" +
"<td><input type=\"button\" VALUE=\">>\" onClick=\"advance( 1 )\">\n" +
"<tr>\n" +
"<td><input type=\"button\" VALUE=\"<<\" onClick=\"backup( 2 )\">\n" +
"<td align=right>month \n" +
"<td><input type=\"text\" value=\"0\" NAME=\"month\" size=\"5\" maxlength=\"30\">\n" +
"<td><input type=\"button\" VALUE=\">>\" onClick=\"advance( 2 )\">\n" +
"<tr>\n" +
"<td><input type=\"button\" VALUE=\"<<\" onClick=\"backup( 3 )\">\n" +
"<td align=right>day \n" +
"<td><input type=\"text\" value=\"0\" NAME=\"day\" size=\"5\" maxlength=\"30\">\n" +
"<td><input type=\"button\" VALUE=\">>\" onClick=\"advance( 3 )\">\n" +
"</table>\n" +
"<p><input type=\"button\" VALUE=\"calculate\" onClick=\"calculate()\">\n" +
"<table>\n" +
"<tr>\n" +
"<td align=right>Moon's age from new moon : \n" +
"<td><input type=\"text\" value=\"0\" NAME=\"age\" size=\"5\" maxlength=\"30\">\n" +
"<td> days\n" +
"<td align=right>Moon is : \n" +
"<td><input type=\"text\" value=\"0\" NAME=\"faz\" size=\"20\" maxlength=\"30\">\n" +
"<tr>\n" +
"<td align=right>Distance : \n" +
"<td><input type=\"text\" value=\"0\" NAME=\"dst\" size=\"5\" maxlength=\"30\">\n" +
"<td> Earth radii\n" +
"<tr>\n" +
"<td align=right>Ecliptic latitude : \n" +
"<td><input type=\"text\" value=\"0\" NAME=\"lat\" size=\"5\" maxlength=\"30\">\n" +
"<td> degrees \n" +
"<tr>\n" +
"<td align=right>Ecliptic longitude :\n" +
"<td><input type=\"text\" value=\"0\" NAME=\"lon\" size=\"5\" maxlength=\"30\">\n" +
"<td> degrees\n" +
"\n" +
"</table>\n" +
"<p><input type=\"button\" VALUE=\"clear\" onClick=\"allclear()\">\n" +
"</form>\n" +
"</center>\n" +
"\n" +
"<hr>\n" +
"\n" +
"<h3><a name=contents>Contents</h3>\n" +
"<ol>\n" +
"<li><a href=\"#about\">About</a>\n" +
"<li><a href=\"#source\">Source code</a>\n" +
"<li><a href=\"#discussion\">Discussion</a>\n" +
"</ol>\n" +
"\n" +
"<hr>\n" +
"\n" +
"<h4>1. <a name=about>About</h4>\n" +
"\n" +
"<p>This JavaScript program calculates the phase and position of the moon for a given date. It was adapted from a BASIC program from the <i>Astronomical Computing</i> column of Sky & Telescope</a>, April 1994. \n" +
"\n" +
"<p>The calculator will initialize itself, if possible, to your computer's day, month, and year. The day, month, and year can be changed using the buttons on the calculator. To advance press one of the [ >> ] keys; to backup, press one of the [ << ] keys.\n" +
"\n" +
"<p>Return to <a href=\"#contents\">Contents</a> \n" +
"\n" +
"<hr>\n" +
"\n" +
"<h4>2. <a name=source>Source Code</h4>\n" +
"\n" +
"<p>The Java Script source code for this program can be viewed by using the View|Source command of your web browser.\n" +
"\n" +
"<p>You may use or modify this source code in any way you find useful, provided that you agree that the author has no warranty, obligations or liability. You must determine the suitablility of this source code for your use.\n" +
"\n" +
"<p>Return to <a href=\"#contents\">Contents</a> \n" +
"\n" +
"<hr>\n" +
"\n" +
"<h4>3. <a name=discussion>Discussion</h4>\n" +
"\n" +
"<p>This program helps anyone who needs to know the Moon's phase (age), distance, and position along the ecliptic on any date within several thousand years in the past or future.\n" +
"\n" +
"<p>The ecliptic longitude is measured from the vernal equinox along the ecliptic in the direction of the sun's apparent motion through the stars. The moon's ecliptic longitude is calculated as well as the corresponding zodiac constellation. The ecliptic latitude is positive if north of the ecliptic and negative if south. The age of the moon in days as well as its visual phase are given. \n" +
"\n" +
"<p>Return to <a href=\"#contents\">Contents</a> \n" +
"\n" +
"<hr>\n" +
"Chaance Graves\n" +
"</body>";
webView.loadData(myHTMLString,"text/html",null);
}
}And here is the Javascript calculator program in html format.
<html>
<head>
<title>Lunarfinder Calculator</title>
<link rel="stylesheet" type="text/css" href="../standard.css">
<SCRIPT language=JavaScript SRC="../feedback.js"></SCRIPT>
<script language=JavaScript>
<!-- hide
var n0 = parseInt( "0" );
var f0 = parseFloat( "0.0" );
var AG = f0; // Moon's age
var DI = f0; // Moon's distance in earth radii
var LA = f0; // Moon's ecliptic latitude
var LO = f0; // Moon's ecliptic longitude
var Phase = " ";
var Zodiac = " ";
function initialize()
{
var d = new Date();
document.calc.year.value = d.getFullYear();
document.calc.month.value = d.getMonth() + 1;
document.calc.day.value = d.getDate();
}
function calculate()
{
var year = parseInt( document.calc.year.value, 10 );
var month = parseInt( document.calc.month.value, 10 );
var day = parseInt( document.calc.day.value, 10 );
if( !isdayofmonth( year, month, day ) )
{
alert( "Invalid date" );
return;
}
moon_posit( year, month, day );
document.calc.age.value = round2( AG );
document.calc.dst.value = round2( DI );
document.calc.faz.value = Phase;
document.calc.lat.value = round2( LA );
document.calc.lon.value = round2( LO );
document.calc.sgn.value = Zodiac;
}
var n28 = parseInt( "28" );
var n30 = parseInt( "30" );
var n31 = parseInt( "31" );
var dim = new Array( n31, n28, n31, n30, n31, n30, n31, n31, n30, n31, n30, n31 );
function isdayofmonth( y, m, d )
{
if( m != 2 )
{
if( 1 <= d && d <= dim[m-1] )
return true;
else
return false;
}
var feb = dim[1];
if( isleapyear( y ) )
feb += 1; // is leap year
if( 1 <= d && d <= feb )
return true;
return false;
}
function isleapyear( y )
{
var x = Math.floor( y - 4*Math.floor( y/4 ) );
var w = Math.floor( y - 100*Math.floor( y/100 ) );
var z = Math.floor( y - 400*Math.floor( y/400 ) );
if( x == 0 ) // possible leap year
{
if( w == 0 && z != 0 )
return false; // not leap year
else
return true; // is leap year
}
return false;
}
function backup( n )
{
var year = parseInt( document.calc.year.value, 10 );
var month = parseInt( document.calc.month.value, 10 );
var day = parseInt( document.calc.day.value, 10 );
switch( n )
{
case 1:
document.calc.year.value = year - 1;
calculate();
break;
case 2:
if( month < 2 )
{
document.calc.month.value = 12;
document.calc.year.value = year - 1;
}
else
document.calc.month.value = month - 1;
calculate();
break;
case 3:
if( day < 2 )
{
if( month < 2 )
{
document.calc.month.value = 12;
document.calc.year.value = year - 1;
}
else
document.calc.month.value = month - 1;
month = parseInt( document.calc.month.value, 10 );
if( month == 2 && isleapyear( year ) )
document.calc.day.value = 29;
else
document.calc.day.value = dim[month-1];
}
else
document.calc.day.value = day - 1;
calculate();
break;
}
}
function advance( n )
{
var year = parseInt( document.calc.year.value, 10 );
var month = parseInt( document.calc.month.value, 10 );
var day = parseInt( document.calc.day.value, 10 );
switch( n )
{
case 1:
document.calc.year.value = year + 1;
calculate();
break;
case 2:
if( month < 12 )
document.calc.month.value = month + 1;
else
{
document.calc.month.value = 1;
document.calc.year.value = year + 1;
}
calculate();
break;
case 3:
if( isdayofmonth( year, month, day + 1 ) )
document.calc.day.value = day + 1;
else
{
if( month < 12 )
document.calc.month.value = month + 1;
else
{
document.calc.month.value = 1;
document.calc.year.value = year + 1;
}
document.calc.day.value = 1;
}
calculate();
break;
}
}
// compute moon position and phase
function moon_posit( Y, M, D )
{
var YY = n0;
var MM = n0;
var K1 = n0;
var K2 = n0;
var K3 = n0;
var JD = n0;
var IP = f0;
var DP = f0;
var NP = f0;
var RP = f0;
// calculate the Julian date at 12h UT
YY = Y - Math.floor( ( 12 - M ) / 10 );
MM = M + 9;
if( MM >= 12 ) MM = MM - 12;
K1 = Math.floor( 365.25 * ( YY + 4712 ) );
K2 = Math.floor( 30.6 * MM + 0.5 );
K3 = Math.floor( Math.floor( ( YY / 100 ) + 49 ) * 0.75 ) - 38;
JD = K1 + K2 + D + 59; // for dates in Julian calendar
if( JD > 2299160 ) JD = JD - K3; // for Gregorian calendar
// calculate moon's age in days
IP = normalize( ( JD - 2451550.1 ) / 29.530588853 );
AG = IP*29.53;
if( AG < 1.84566 ) Phase = "NEW";
else if( AG < 5.53699 ) Phase = "Evening crescent";
else if( AG < 9.22831 ) Phase = "First quarter";
else if( AG < 12.91963 ) Phase = "Waxing gibbous";
else if( AG < 16.61096 ) Phase = "FULL";
else if( AG < 20.30228 ) Phase = "Waning gibbous";
else if( AG < 23.99361 ) Phase = "Last quarter";
else if( AG < 27.68493 ) Phase = "Morning crescent";
else Phase = "NEW";
IP = IP*2*Math.PI; // Convert phase to radians
// calculate moon's distance
DP = 2*Math.PI*normalize( ( JD - 2451562.2 ) / 27.55454988 );
DI = 60.4 - 3.3*Math.cos( DP ) - 0.6*Math.cos( 2*IP - DP ) - 0.5*Math.cos( 2*IP );
// calculate moon's ecliptic latitude
NP = 2*Math.PI*normalize( ( JD - 2451565.2 ) / 27.212220817 );
LA = 5.1*Math.sin( NP );
// calculate moon's ecliptic longitude
RP = normalize( ( JD - 2451555.8 ) / 27.321582241 );
LO = 360*RP + 6.3*Math.sin( DP ) + 1.3*Math.sin( 2*IP - DP ) + 0.7*Math.sin( 2*IP );
if( LO < 33.18 ) Zodiac = "Pisces";
else if( LO < 51.16 ) Zodiac = "Aries";
else if( LO < 93.44 ) Zodiac = "Taurus";
else if( LO < 119.48 ) Zodiac = "Gemini";
else if( LO < 135.30 ) Zodiac = "Cancer";
else if( LO < 173.34 ) Zodiac = "Leo";
else if( LO < 224.17 ) Zodiac = "Virgo";
else if( LO < 242.57 ) Zodiac = "Libra";
else if( LO < 271.26 ) Zodiac = "Scorpio";
else if( LO < 302.49 ) Zodiac = "Sagittarius";
else if( LO < 311.72 ) Zodiac = "Capricorn";
else if( LO < 348.58 ) Zodiac = "Aquarius";
else Zodiac = "Pisces";
// so longitude is not greater than 360!
if ( LO > 360 ) LO = LO - 360;
}
// round to 2 decimal places
function round2( x )
{
return ( Math.round( 100*x )/100.0 );
}
// normalize values to range 0...1
function normalize( v )
{
v = v - Math.floor( v );
if( v < 0 )
v = v + 1;
return v;
}
// clear input
function allclear()
{
document.calc.year.value='0';
document.calc.month.value='0';
document.calc.day.value='0';
}
function Moondata(distance, ecliptic_latitude, ecliptic_longitude, Moon_phase) {
this distance = distance;
this ecliptic_latitude = ecliptic_latitude;
this ecliptic_longitude = ecliptic_longitude;
this Moon_phase = Moon_phase;
}
// unhide -->
</script>
</head>
<body bgcolor="maroon" text="white" onLoad=initialize()>
<h2>Lunarfinder Calculator</h2>
<h4>ECEN 489
Project 3</h4>
<center>
<form name="calc">
<table>
<tr>
<td><input type="button" VALUE="<<" onClick="backup( 1 )">
<td align=right>year
<td><input type="text" value="0" NAME="year" size="5" maxlength="30">
<td><input type="button" VALUE=">>" onClick="advance( 1 )">
<tr>
<td><input type="button" VALUE="<<" onClick="backup( 2 )">
<td align=right>month
<td><input type="text" value="0" NAME="month" size="5" maxlength="30">
<td><input type="button" VALUE=">>" onClick="advance( 2 )">
<tr>
<td><input type="button" VALUE="<<" onClick="backup( 3 )">
<td align=right>day
<td><input type="text" value="0" NAME="day" size="5" maxlength="30">
<td><input type="button" VALUE=">>" onClick="advance( 3 )">
</table>
<p><input type="button" VALUE="calculate" onClick="calculate()">
<table>
<tr>
<td align=right>Moon's age from new moon :
<td><input type="text" value="0" NAME="age" size="5" maxlength="30">
<td> days
<td align=right>Moon is :
<td><input type="text" value="0" NAME="faz" size="20" maxlength="30">
<tr>
<td align=right>Distance :
<td><input type="text" value="0" NAME="dst" size="5" maxlength="30">
<td> Earth radii
<tr>
<td align=right>Ecliptic latitude :
<td><input type="text" value="0" NAME="lat" size="5" maxlength="30">
<td> degrees
<tr>
<td align=right>Ecliptic longitude :
<td><input type="text" value="0" NAME="lon" size="5" maxlength="30">
<td> degrees
</table>
<p><input type="button" VALUE="clear" onClick="allclear()">
</form>
</center>
<hr>
<h3><a name=contents>Contents</h3>
<ol>
<li><a href="#about">About</a>
<li><a href="#source">Source code</a>
<li><a href="#discussion">Discussion</a>
</ol>
<hr>
<h4>1. <a name=about>About</h4>
<p>This JavaScript program calculates the phase and position of the moon for a given date. It was adapted from a BASIC program from the <i>Astronomical Computing</i> column of Sky & Telescope</a>, April 1994.
<p>The calculator will initialize itself, if possible, to your computer's day, month, and year. The day, month, and year can be changed using the buttons on the calculator. To advance press one of the [ >> ] keys; to backup, press one of the [ << ] keys.
<p>Return to <a href="#contents">Contents</a>
<hr>
<h4>2. <a name=source>Source Code</h4>
<p>The Java Script source code for this program can be viewed by using the View|Source command of your web browser.
<p>You may use or modify this source code in any way you find useful, provided that you agree that the author has no warranty, obligations or liability. You must determine the suitablility of this source code for your use.
<p>Return to <a href="#contents">Contents</a>
<hr>
<h4>3. <a name=discussion>Discussion</h4>
<p>This program helps anyone who needs to know the Moon's phase (age), distance, and position along the ecliptic on any date within several thousand years in the past or future.
<p>The ecliptic longitude is measured from the vernal equinox along the ecliptic in the direction of the sun's apparent motion through the stars. The moon's ecliptic longitude is calculated as well as the corresponding zodiac constellation. The ecliptic latitude is positive if north of the ecliptic and negative if south. The age of the moon in days as well as its visual phase are given.
<p>Return to <a href="#contents">Contents</a>
<hr>
Chaance Graves
</body>- Framework for Augmented reality activity and Simple two button interface was created.
- 3D rendered sphere model was successfully created on placed on the Surfaceview of the phone screen.
- The Javascript application for calculating the defined Moon data was successfully utilized to return values.
- 2D image wrapping of sphere indicating the phases from the calculator - 8 phases can be rendered with a switch/case statement on top of the the Sphere.
- Save the data to a .txt file for the user to access in a later time.
- A more defined robust method to convert ecliptic coordinates to phone orientation data parameters. (yaw, pitch, roll)