浏览代码

Flugbahn-Chart

master
gitsvn 12 年前
父节点
当前提交
e0876b070b

+ 3
- 0
res/values-de/strings.xml 查看文件

@@ -56,6 +56,9 @@
<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="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_TitleLable">Flugbahn</string>
<string name="fcChart_TitleXAxis">Distanz [m]</string>

+ 3
- 0
res/values/strings.xml 查看文件

@@ -57,6 +57,9 @@
<string name="caption_FillAllMandatoryFields">To start the calculation all parameter fields must be filled.</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_TitleLable">Trajectory</string>
<string name="fcChart_TitleXAxis">Distance [m]</string>

+ 57
- 49
src/ch/spherIC/recurvebowsight/RBSMainActivity.java 查看文件

@@ -1,8 +1,8 @@
package ch.spherIC.recurvebowsight;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
@@ -95,6 +95,9 @@ public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDi
private static final double CENTI = 0.01;
private static final double MILLI = 0.001;
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 ScrollView paramsScrollView;
@@ -136,7 +139,7 @@ public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDi
private Double startAngle;
private String selectedHeVS;
private AlertDialog calculationAlert;
private ProgressDialog progressDialog;
private FlightCurveChart flightCurveChart;
@@ -151,10 +154,6 @@ public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDi
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());
RBSDatabaseHelper.setContext(this);
RBSDatabaseHelper.getInstance().initializeDB();
@@ -750,9 +749,9 @@ public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDi
this.scSightSpinner.fireSelectionChangedEvent();
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 {
this.arrowDiameterTxtFld.setText("");
@@ -813,6 +812,8 @@ public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDi
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
this.progressDialog = ProgressDialog.show(this, null, getResources().getString(R.string.caption_Calculating), true, false);
CalculationTask calcTask = new CalculationTask();
TrajectoryCalculator calculator = new TrajectoryCalculator(Double.valueOf(this.arrowDiameterTxtFld.getText().toString().trim()) * MILLI, //
Double.valueOf(this.arrowCwTxtFld.getText().toString().trim()), //
@@ -831,8 +832,6 @@ public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDi
calculator.setStartAngle(0d);
calcTask.execute(calculator);
this.calculationAlert.show();
} else {
Toast toast = Toast.makeText(this, getResources().getString(R.string.caption_FillAllMandatoryFields), Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
@@ -840,17 +839,61 @@ public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDi
}
}
@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
public void onCalculationDone(final Double[][] flightCurve, final Double startAngle, final Double[] maxHCurve) {
this.startAngle = startAngle;
updateFlightCurveChart(flightCurve);
fillFlightCurveTxtFld(flightCurve, startAngle, maxHCurve);
calculateSettings();
if (this.calculationAlert != null) {
this.calculationAlert.dismiss();
if (this.progressDialog != null) {
this.progressDialog.dismiss();
}
this.txtViewSight.doSingleTouch();
@@ -874,41 +917,6 @@ public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDi
}
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.
*/

+ 2
- 0
src/ch/spherIC/recurvebowsight/TrajectoryCalculation.java 查看文件

@@ -7,6 +7,8 @@ package ch.spherIC.recurvebowsight;
public interface TrajectoryCalculation {
void updateTrajectoryTxtFld(Integer step, Double[] flightCurveRow, Double startAngle, Double[] maxHCurve);
void onCalculationDone(Double[][] flightCurve, Double startAngle, Double[] maxHCurve);
}

+ 1
- 1
src/ch/spherIC/recurvebowsight/components/FlightCurveChart.java 查看文件

@@ -164,8 +164,8 @@ public class FlightCurveChart {
yLbls = 20;
}
this.mRenderer.setYLabels(yLbls);
this.mRenderer.setYAxisMin(minH - dy);
this.mRenderer.setYAxisMax(maxH + dy);
this.mRenderer.setYLabels(yLbls);
}
}

+ 40
- 19
src/ch/spherIC/recurvebowsight/logic/CalculationTask.java 查看文件

@@ -9,47 +9,47 @@ import android.os.AsyncTask;
/**
* @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;
TrajectoryCalculator calculator;
@Override
protected TrajectoryCalculator doInBackground(final TrajectoryCalculator... params) {
TrajectoryCalculator calculator = params[0];
this.calculator = params[0];
boolean exitLoop = false;
Double angleX = 0.0;
Double angleHigh = 0.0;
Double angleLow = calculator.getStartAngle() + PHI;
Double angleLow = this.calculator.getStartAngle() + PHI;
Double[][] results;
Double frictionCoefficient = calculator.calculateFrictionCoeficient();
Double frictionCoefficient = this.calculator.calculateFrictionCoeficient();
// Startwerte für angleLow und angleHigh berechnen
do {
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;
do {
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
do {
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;
} else {
angleHigh = angleX;
@@ -61,13 +61,20 @@ public class CalculationTask extends AsyncTask<TrajectoryCalculator, Void, Traje
} 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) {
Double[] maxHCurve = new Double[] { 0d, 0d };
@@ -84,10 +91,24 @@ public class CalculationTask extends AsyncTask<TrajectoryCalculator, Void, Traje
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
protected void onPostExecute(final TrajectoryCalculator calculator) {
super.onPostExecute(calculator);
calculator.getListener().onCalculationDone(calculator.getFlightCurve(), calculator.getStartAngle(), calculator.getMaxHCurve());
}
private void sleep(final long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

正在加载...
取消
保存