Browse Source

Flugbahn-Chart

master
gitsvn 12 years ago
parent
commit
e0876b070b

+ 3
- 0
res/values-de/strings.xml View File

<string name="caption_FillAllMandatoryFields">Um die Berechnung durchzuführen, müssen alle Parameterfelder abgefüllt sein.</string> <string name="caption_FillAllMandatoryFields">Um die Berechnung durchzuführen, müssen alle Parameterfelder abgefüllt sein.</string>
<string name="caption_Calculating">Berechnung läuft&#8230;</string> <string name="caption_Calculating">Berechnung läuft&#8230;</string>
<!-- --> <!-- -->
<string name="fcChart_StartAngle">Abschusswinkel:\n</string>
<string name="fcChart_MaxHeight">Max. Höhe der Flugbahn:\n</string>
<string name="fcChart_FlightDuration">Flugzeit:\n</string>
<string name="fcChart_Title">Ballistische Flugbahn</string> <string name="fcChart_Title">Ballistische Flugbahn</string>
<string name="fcChart_TitleLable">Flugbahn</string> <string name="fcChart_TitleLable">Flugbahn</string>
<string name="fcChart_TitleXAxis">Distanz [m]</string> <string name="fcChart_TitleXAxis">Distanz [m]</string>

+ 3
- 0
res/values/strings.xml View File

<string name="caption_FillAllMandatoryFields">To start the calculation all parameter fields must be filled.</string> <string name="caption_FillAllMandatoryFields">To start the calculation all parameter fields must be filled.</string>
<string name="caption_Calculating">Calculating&#8230;</string> <string name="caption_Calculating">Calculating&#8230;</string>
<!-- --> <!-- -->
<string name="fcChart_StartAngle">Elevation Angle:\n</string>
<string name="fcChart_MaxHeight">Max. Height of Trajectory:\n</string>
<string name="fcChart_FlightDuration">Flight Duration:\n</string>
<string name="fcChart_Title">Ballistic Trajectory</string> <string name="fcChart_Title">Ballistic Trajectory</string>
<string name="fcChart_TitleLable">Trajectory</string> <string name="fcChart_TitleLable">Trajectory</string>
<string name="fcChart_TitleXAxis">Distance [m]</string> <string name="fcChart_TitleXAxis">Distance [m]</string>

+ 57
- 49
src/ch/spherIC/recurvebowsight/RBSMainActivity.java View File

package ch.spherIC.recurvebowsight; package ch.spherIC.recurvebowsight;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
private static final double CENTI = 0.01; private static final double CENTI = 0.01;
private static final double MILLI = 0.001; private static final double MILLI = 0.001;
private static final int MAX_TRAJ_POINTS = 200; private static final int MAX_TRAJ_POINTS = 200;
private static final String DEF_TEMP = "23";
private static final String DEF_HUMIDITY = "50";
private static final String DEF_DISTANCE = "18";
private ViewFlipper viewFlipper; private ViewFlipper viewFlipper;
private ScrollView paramsScrollView; private ScrollView paramsScrollView;
private Double startAngle; private Double startAngle;
private String selectedHeVS; private String selectedHeVS;
private AlertDialog calculationAlert;
private ProgressDialog progressDialog;
private FlightCurveChart flightCurveChart; private FlightCurveChart flightCurveChart;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} }
this.calculationAlert = new AlertDialog.Builder(this).create();
this.calculationAlert.setCancelable(false); // This blocks the 'BACK' button
this.calculationAlert.setMessage(getApplicationContext().getResources().getString(R.string.caption_Calculating));
UnitConverter.setApplication(getApplication()); UnitConverter.setApplication(getApplication());
RBSDatabaseHelper.setContext(this); RBSDatabaseHelper.setContext(this);
RBSDatabaseHelper.getInstance().initializeDB(); RBSDatabaseHelper.getInstance().initializeDB();
this.scSightSpinner.fireSelectionChangedEvent(); this.scSightSpinner.fireSelectionChangedEvent();
this.scVertScaleMiddleTxtFld.setText(DF.format(archerySetup.getSightVertSkalaMiddle())); this.scVertScaleMiddleTxtFld.setText(DF.format(archerySetup.getSightVertSkalaMiddle()));
this.airTemperatureTxtFld.setText("23");
this.airRelativeHumidityTxtFld.setText("50");
this.shootingDistanzTxtFld.setText("18");
this.airTemperatureTxtFld.setText(DEF_TEMP);
this.airRelativeHumidityTxtFld.setText(DEF_HUMIDITY);
this.shootingDistanzTxtFld.setText(DEF_DISTANCE);
} else { } else {
this.arrowDiameterTxtFld.setText(""); this.arrowDiameterTxtFld.setText("");
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
} }
this.progressDialog = ProgressDialog.show(this, null, getResources().getString(R.string.caption_Calculating), true, false);
CalculationTask calcTask = new CalculationTask(); CalculationTask calcTask = new CalculationTask();
TrajectoryCalculator calculator = new TrajectoryCalculator(Double.valueOf(this.arrowDiameterTxtFld.getText().toString().trim()) * MILLI, // TrajectoryCalculator calculator = new TrajectoryCalculator(Double.valueOf(this.arrowDiameterTxtFld.getText().toString().trim()) * MILLI, //
Double.valueOf(this.arrowCwTxtFld.getText().toString().trim()), // Double.valueOf(this.arrowCwTxtFld.getText().toString().trim()), //
calculator.setStartAngle(0d); calculator.setStartAngle(0d);
calcTask.execute(calculator); calcTask.execute(calculator);
this.calculationAlert.show();
} else { } else {
Toast toast = Toast.makeText(this, getResources().getString(R.string.caption_FillAllMandatoryFields), Toast.LENGTH_LONG); Toast toast = Toast.makeText(this, getResources().getString(R.string.caption_FillAllMandatoryFields), Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0); toast.setGravity(Gravity.CENTER, 0, 0);
} }
} }
@Override
public void updateTrajectoryTxtFld(final Integer step, final Double[] flightCurveRow, final Double startAngle, final Double[] maxHCurve) {
int width = this.flightCurveTxtFld.getMeasuredWidth();
Double[] r1 = flightCurveRow;
switch (step) {
case 0:
this.flightCurveTxtFld.setText("");
this.flightCurveTxtFld.append(getResources().getString(R.string.fcChart_StartAngle) + DF_FC.format(startAngle) + " °\n\n");
this.flightCurveTxtFld.append(getResources().getString(R.string.fcChart_MaxHeight) + DF_FC.format(maxHCurve[0])
+ " m / "
+ DF_FC.format(maxHCurve[0] + Double.valueOf(this.arrowNockHeightTxtFld.getText().toString().trim()))
+ " m, [t = " + DF_FC.format(maxHCurve[1]) + " s]\n\n");
this.flightCurveTxtFld.append(getResources().getString(R.string.fcChart_FlightDuration)
+ DF_FC.format(r1[TrajectoryCalculator.IDX_T])
+ " sec\n\n");
SpannableString line = new SpannableString("t [sec]\tVx [m/s]\tVy [m/s]\tx [m]\ty [m]\n\n");
line.setSpan(new TabStopSpan.Standard(width / 5), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 2), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 3), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 4), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
this.flightCurveTxtFld.append(line);
break;
case 1:
line = new SpannableString(DF_FC.format(r1[TrajectoryCalculator.IDX_T]) + '\t'
+ DF_FC.format(r1[TrajectoryCalculator.IDX_VX]) + '\t'
+ DF_FC.format(r1[TrajectoryCalculator.IDX_VY]) + '\t'
+ DF_FC.format(r1[TrajectoryCalculator.IDX_X]) + '\t'
+ DF_FC.format(r1[TrajectoryCalculator.IDX_Y]) + "\n");
line.setSpan(new TabStopSpan.Standard(width / 5), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 2), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 3), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 4), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
this.flightCurveTxtFld.append(line);
break;
default:
break;
}
}
@Override @Override
public void onCalculationDone(final Double[][] flightCurve, final Double startAngle, final Double[] maxHCurve) { public void onCalculationDone(final Double[][] flightCurve, final Double startAngle, final Double[] maxHCurve) {
this.startAngle = startAngle; this.startAngle = startAngle;
updateFlightCurveChart(flightCurve); updateFlightCurveChart(flightCurve);
fillFlightCurveTxtFld(flightCurve, startAngle, maxHCurve);
calculateSettings(); calculateSettings();
if (this.calculationAlert != null) {
this.calculationAlert.dismiss();
if (this.progressDialog != null) {
this.progressDialog.dismiss();
} }
this.txtViewSight.doSingleTouch(); this.txtViewSight.doSingleTouch();
} }
private void fillFlightCurveTxtFld(final Double[][] flightCurve, final Double startAngle,
final Double[] maxHCurve) {
this.flightCurveTxtFld.setText("");
this.flightCurveTxtFld.append("Abschusswinkel:\n" + DF_FC.format(startAngle) + " °\n\n");
this.flightCurveTxtFld.append("Max. Höhe der Flugbahn:\n" + DF_FC.format(maxHCurve[0])
+ " m / " + DF_FC.format(maxHCurve[0] + Double.valueOf(this.arrowNockHeightTxtFld.getText().toString().trim()))
+ " m, [t = " + DF_FC.format(maxHCurve[1]) + " s]\n\n");
this.flightCurveTxtFld.append("Flugzeit:\n"
+ DF_FC.format(flightCurve[flightCurve.length - 1][TrajectoryCalculator.IDX_T])
+ " sec\n\n");
int width = this.flightCurveTxtFld.getMeasuredWidth();
SpannableString line = new SpannableString("t [sec]\tVx [m/s]\tVy [m/s]\tx [m]\ty [m]\n\n");
line.setSpan(new TabStopSpan.Standard(width / 5), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 2), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 3), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 4), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
this.flightCurveTxtFld.append(line);
for (int i = 0; i < flightCurve.length; i++) {
Double[] r1 = flightCurve[i];
line = new SpannableString(DF_FC.format(r1[TrajectoryCalculator.IDX_T]) + '\t'
+ DF_FC.format(r1[TrajectoryCalculator.IDX_VX]) + '\t'
+ DF_FC.format(r1[TrajectoryCalculator.IDX_VY]) + '\t'
+ DF_FC.format(r1[TrajectoryCalculator.IDX_X]) + '\t'
+ DF_FC.format(r1[TrajectoryCalculator.IDX_Y]) + "\n");
line.setSpan(new TabStopSpan.Standard(width / 5), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 2), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 3), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
line.setSpan(new TabStopSpan.Standard(width / 5 * 4), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
this.flightCurveTxtFld.append(line);
}
}
/** /**
* Berechnet die definitve Visiereinstellung anhand des berechneten Flugbahnwinkels. * Berechnet die definitve Visiereinstellung anhand des berechneten Flugbahnwinkels.
*/ */

+ 2
- 0
src/ch/spherIC/recurvebowsight/TrajectoryCalculation.java View File

public interface TrajectoryCalculation { public interface TrajectoryCalculation {
void updateTrajectoryTxtFld(Integer step, Double[] flightCurveRow, Double startAngle, Double[] maxHCurve);
void onCalculationDone(Double[][] flightCurve, Double startAngle, Double[] maxHCurve); void onCalculationDone(Double[][] flightCurve, Double startAngle, Double[] maxHCurve);
} }

+ 1
- 1
src/ch/spherIC/recurvebowsight/components/FlightCurveChart.java View File

yLbls = 20; yLbls = 20;
} }
this.mRenderer.setYLabels(yLbls);
this.mRenderer.setYAxisMin(minH - dy); this.mRenderer.setYAxisMin(minH - dy);
this.mRenderer.setYAxisMax(maxH + dy); this.mRenderer.setYAxisMax(maxH + dy);
this.mRenderer.setYLabels(yLbls);
} }
} }

+ 40
- 19
src/ch/spherIC/recurvebowsight/logic/CalculationTask.java View File

/** /**
* @author FC Smilari * @author FC Smilari
*/ */
public class CalculationTask extends AsyncTask<TrajectoryCalculator, Void, TrajectoryCalculator> {
public class CalculationTask extends AsyncTask<TrajectoryCalculator, Integer, TrajectoryCalculator> {
private static final Double PHI = 1.0; private static final Double PHI = 1.0;
TrajectoryCalculator calculator;
@Override @Override
protected TrajectoryCalculator doInBackground(final TrajectoryCalculator... params) { protected TrajectoryCalculator doInBackground(final TrajectoryCalculator... params) {
TrajectoryCalculator calculator = params[0];
this.calculator = params[0];
boolean exitLoop = false; boolean exitLoop = false;
Double angleX = 0.0; Double angleX = 0.0;
Double angleHigh = 0.0; Double angleHigh = 0.0;
Double angleLow = calculator.getStartAngle() + PHI;
Double angleLow = this.calculator.getStartAngle() + PHI;
Double[][] results; Double[][] results;
Double frictionCoefficient = calculator.calculateFrictionCoeficient();
Double frictionCoefficient = this.calculator.calculateFrictionCoeficient();
// Startwerte für angleLow und angleHigh berechnen // Startwerte für angleLow und angleHigh berechnen
do { do {
angleLow -= PHI; angleLow -= PHI;
results = calculator.calculateTrajectory(angleLow, frictionCoefficient);
} while (results[results.length - 1][TrajectoryCalculator.IDX_Y] - calculator.getDeltaHeight() > 0);
results = this.calculator.calculateTrajectory(angleLow, frictionCoefficient);
} while (results[results.length - 1][TrajectoryCalculator.IDX_Y] - this.calculator.getDeltaHeight() > 0);
angleHigh = angleLow; angleHigh = angleLow;
do { do {
angleHigh += PHI; angleHigh += PHI;
results = calculator.calculateTrajectory(angleHigh, frictionCoefficient);
} while (results[results.length - 1][TrajectoryCalculator.IDX_Y] - calculator.getDeltaHeight() < 0);
results = this.calculator.calculateTrajectory(angleHigh, frictionCoefficient);
} while (results[results.length - 1][TrajectoryCalculator.IDX_Y] - this.calculator.getDeltaHeight() < 0);
// Winkel suchen mit Hilfe der Regula Falsi und Flugbahnberechnungsiterationen // Winkel suchen mit Hilfe der Regula Falsi und Flugbahnberechnungsiterationen
do { do {
angleX = (angleHigh + angleLow) / 2; angleX = (angleHigh + angleLow) / 2;
results = calculator.calculateTrajectory(angleX, frictionCoefficient);
results = this.calculator.calculateTrajectory(angleX, frictionCoefficient);
if (Math.abs(calculator.getDeltaHeight() - results[results.length - 1][TrajectoryCalculator.IDX_Y])
> calculator.getCalculationPrecision()) {
if (Math.abs(this.calculator.getDeltaHeight() - results[results.length - 1][TrajectoryCalculator.IDX_Y])
> this.calculator.getCalculationPrecision()) {
if (results[results.length - 1][TrajectoryCalculator.IDX_Y] - calculator.getDeltaHeight() < 0) {
if (results[results.length - 1][TrajectoryCalculator.IDX_Y] - this.calculator.getDeltaHeight() < 0) {
angleLow = angleX; angleLow = angleX;
} else { } else {
angleHigh = angleX; angleHigh = angleX;
} while (!exitLoop); } while (!exitLoop);
calculator.setStartAngle(angleX);
calculator.setFlightCurve(results);
calculator.setMaxHCurve(calculateMaxHeight(results));
this.calculator.setStartAngle(angleX);
this.calculator.setFlightCurve(results);
this.calculator.setMaxHCurve(calculateMaxHeight(results));
return calculator;
}
publishProgress(0, results.length - 1);
sleep(5);
for (int i = 0; i < results.length; i++) {
publishProgress(1, i);
sleep(5);
}
return this.calculator;
}
public static Double[] calculateMaxHeight(final Double[][] flightCurve) { public static Double[] calculateMaxHeight(final Double[][] flightCurve) {
Double[] maxHCurve = new Double[] { 0d, 0d }; Double[] maxHCurve = new Double[] { 0d, 0d };
return maxHCurve; return maxHCurve;
} }
@Override
protected void onProgressUpdate(final Integer... values) {
super.onProgressUpdate(values);
this.calculator.getListener().updateTrajectoryTxtFld(values[0], this.calculator.getFlightCurve()[values[1]], this.calculator.getStartAngle(),
this.calculator.getMaxHCurve());
}
@Override @Override
protected void onPostExecute(final TrajectoryCalculator calculator) { protected void onPostExecute(final TrajectoryCalculator calculator) {
super.onPostExecute(calculator); super.onPostExecute(calculator);
calculator.getListener().onCalculationDone(calculator.getFlightCurve(), calculator.getStartAngle(), calculator.getMaxHCurve()); calculator.getListener().onCalculationDone(calculator.getFlightCurve(), calculator.getStartAngle(), calculator.getMaxHCurve());
} }
private void sleep(final long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }

Loading…
Cancel
Save