Version für alte Androidversionen der Visiereinstellung für Recurvebogen.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  1. package ch.spherIC.recurvebowsight;
  2. import android.app.Activity;
  3. import android.app.Dialog;
  4. import android.app.ProgressDialog;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.pm.ActivityInfo;
  8. import android.os.Bundle;
  9. import android.os.Handler;
  10. import android.text.Editable;
  11. import android.text.SpannableString;
  12. import android.text.Spanned;
  13. import android.text.TextWatcher;
  14. import android.text.style.TabStopSpan;
  15. import android.view.Gravity;
  16. import android.view.Menu;
  17. import android.view.MenuItem;
  18. import android.view.MotionEvent;
  19. import android.view.View;
  20. import android.view.View.OnClickListener;
  21. import android.view.View.OnTouchListener;
  22. import android.view.inputmethod.InputMethodManager;
  23. import android.widget.AdapterView;
  24. import android.widget.AdapterView.OnItemSelectedListener;
  25. import android.widget.Button;
  26. import android.widget.LinearLayout;
  27. import android.widget.LinearLayout.LayoutParams;
  28. import android.widget.ScrollView;
  29. import android.widget.TextView;
  30. import android.widget.Toast;
  31. import android.widget.ViewFlipper;
  32. import ch.spherIC.recurvebowsight.components.FlightCurveChart;
  33. import ch.spherIC.recurvebowsight.components.FontArrayAdapter;
  34. import ch.spherIC.recurvebowsight.components.FontTextView;
  35. import ch.spherIC.recurvebowsight.components.RiserSpinner;
  36. import ch.spherIC.recurvebowsight.components.SightSpinner;
  37. import ch.spherIC.recurvebowsight.components.XSpinner;
  38. import ch.spherIC.recurvebowsight.components.XTextView;
  39. import ch.spherIC.recurvebowsight.configuration.MainConfigurationActivity;
  40. import ch.spherIC.recurvebowsight.database.RBSDatabaseHelper;
  41. import ch.spherIC.recurvebowsight.database.dao.ArcherySetupDao;
  42. import ch.spherIC.recurvebowsight.database.dao.RiserDao;
  43. import ch.spherIC.recurvebowsight.database.dao.SightDao;
  44. import ch.spherIC.recurvebowsight.dialog.ChooseArcherySetupDlg.ChooseArcherySetupDlgDismissListener;
  45. import ch.spherIC.recurvebowsight.logic.CalculationTask;
  46. import ch.spherIC.recurvebowsight.logic.TrajectoryCalculator;
  47. import ch.spherIC.recurvebowsight.model.IArcherySetup;
  48. import ch.spherIC.recurvebowsight.model.IRiser;
  49. import ch.spherIC.recurvebowsight.model.ISight;
  50. import ch.spherIC.recurvebowsight.model.Riser;
  51. import ch.spherIC.recurvebowsight.model.Sight;
  52. import ch.spherIC.recurvebowsight.utilities.CompatibilityUtil;
  53. import ch.spherIC.recurvebowsight.utilities.PlatformUtils;
  54. import ch.spherIC.recurvebowsight.utilities.UnitConverter;
  55. import org.achartengine.GraphicalView;
  56. import org.achartengine.model.XYSeries;
  57. import java.text.DecimalFormat;
  58. import java.util.ArrayList;
  59. import java.util.List;
  60. import java.util.StringTokenizer;
  61. public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDismissListener, TrajectoryCalculation {
  62. public static final DecimalFormat DF = new DecimalFormat("0.##");
  63. public static final DecimalFormat DF_FC = new DecimalFormat("0.000");
  64. public static final DecimalFormat DF_1 = new DecimalFormat("0.00");
  65. public static final DecimalFormat DF_EVS = new DecimalFormat("0.#");
  66. public static final int DLG_CHOOSE_ARCHERYSETUP = 0;
  67. public static final int DLG_USERGUIDE_PARAMS = 1;
  68. public static final int DLG_USERGUIDE_SIGHT = 2;
  69. public static final int DLG_ABOUT = 3;
  70. private static final Double ANGLE_90 = 90d;
  71. private static final int MIN_DISTANCE = 50;
  72. private static final double CENTI = 0.01;
  73. private static final double MILLI = 0.001;
  74. private static final int MAX_TRAJ_POINTS = 200;
  75. private static final String DEF_TEMP = "23";
  76. private static final String DEF_HUMIDITY = "50";
  77. private static final String DEF_DISTANCE = "18";
  78. private ViewFlipper viewFlipper;
  79. private ScrollView paramsScrollView;
  80. private ScrollView sightCfgScrollView;
  81. private float lastX;
  82. private XTextView txtViewParams;
  83. private XTextView txtViewResults;
  84. private XTextView txtViewSight;
  85. private TextView arrowDiameterTxtFld;
  86. private TextView arrowCwTxtFld;
  87. private TextView arrowWeightTxtFld;
  88. private TextView bowPulloutTxtFld;
  89. private TextView arrowV0TxtFld;
  90. private TextView hNATxtFld;
  91. private TextView nockRaisingTxtFld;
  92. private TextView braceHeightTxtFld;
  93. private TextView airTemperatureTxtFld;
  94. private TextView airRelativeHumidityTxtFld;
  95. private TextView shootingDistanzTxtFld;
  96. private TextView arrowNockHeightTxtFld;
  97. private TextView targetCenterHeightTxtFld;
  98. private XSpinner calcTimeIntervalCboBox;
  99. private XSpinner calcAccuracyCboBox;
  100. private RiserSpinner scRiserSpinner;
  101. private TextView scVvisHTxtFld;
  102. private TextView scVvisVTxtFld;
  103. private SightSpinner scSightSpinner;
  104. private XSpinner scHeVSSpinner;
  105. private TextView scHeVSTxtFld;
  106. private TextView scaVTxtFld;
  107. private TextView scaHTxtFld;
  108. private TextView scVertScaleRngTxtFld;
  109. private TextView scVertScaleMiddleTxtFld;
  110. private FontTextView scEvSValue;
  111. private Button calcSettingBtn;
  112. private XTextView flightCurveTxtFld;
  113. private boolean showInfoMenu;
  114. private IArcherySetup selectedArcherySetup;
  115. private Double startAngle;
  116. private String selectedHeVS;
  117. private ProgressDialog progressDialog;
  118. private FlightCurveChart flightCurveChart;
  119. @Override
  120. public void onCreate(final Bundle savedInstanceState) {
  121. super.onCreate(savedInstanceState);
  122. setContentView(R.layout.rbs_main);
  123. PlatformUtils.getPlatformSelectionColor(getApplicationContext());
  124. if (CompatibilityUtil.isTablet(getApplicationContext())) {
  125. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
  126. } else {
  127. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  128. }
  129. UnitConverter.setApplication(getApplication());
  130. RBSDatabaseHelper.setContext(this);
  131. RBSDatabaseHelper.getInstance().initializeDB();
  132. initializeComponents();
  133. addTouchListeners();
  134. addValueChangeListeners();
  135. xTextViewUp(this.txtViewParams);
  136. this.calcTimeIntervalCboBox.setAdapter(new FontArrayAdapter<String>(this, R.layout.rbs_spinner,
  137. getResources().getStringArray(R.array.CalculationTimeIntervals),
  138. this.calcTimeIntervalCboBox));
  139. this.calcAccuracyCboBox.setAdapter(new FontArrayAdapter<String>(this, R.layout.rbs_spinner,
  140. getResources().getStringArray(R.array.CalculationAccuracies),
  141. this.calcAccuracyCboBox));
  142. loadRiserSpinner();
  143. loadSightSpinner();
  144. addRiserAndSightSpinnerListeners();
  145. GraphicalView flightCurveChartView;
  146. LinearLayout layout;
  147. this.flightCurveChart = new FlightCurveChart();
  148. flightCurveChartView = this.flightCurveChart.getView(this);
  149. layout = (LinearLayout) findViewById(R.id.ballisticResults);
  150. layout.addView(flightCurveChartView, 0, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1f));
  151. }
  152. private void loadRiserSpinner() {
  153. IRiser selectedRiser = this.scRiserSpinner.getSelectedRiser();
  154. List<IRiser> risers = RiserDao.getInstance().loadAll();
  155. risers.add(0, new Riser(-999, getResources().getString(R.string.caption_NoSelection), "", null, null, null));
  156. this.scRiserSpinner.setAdapter(new FontArrayAdapter<IRiser>(this, R.layout.rbs_spinner, risers, this.scRiserSpinner));
  157. if (selectedRiser != null) {
  158. this.scRiserSpinner.setSelectedRiser(selectedRiser);
  159. }
  160. }
  161. private void loadSightSpinner() {
  162. ISight selectedSight = this.scSightSpinner.getSelectedSight();
  163. List<ISight> sights = SightDao.getInstance().loadAll();
  164. sights.add(0, new Sight(-999, getResources().getString(R.string.caption_NoSelection), "", null, null, "", null, null));
  165. this.scSightSpinner.setAdapter(new FontArrayAdapter<ISight>(this, R.layout.rbs_spinner, sights, this.scSightSpinner));
  166. if (selectedSight != null) {
  167. this.scSightSpinner.setSelectedSight(selectedSight);
  168. }
  169. }
  170. @Override
  171. protected void onSaveInstanceState(final Bundle outState) {
  172. super.onSaveInstanceState(outState);
  173. outState.putInt("ViewFlipper.SelectedView", this.viewFlipper.getDisplayedChild());
  174. if (this.selectedArcherySetup != null) {
  175. outState.putLong("SelectedArcherySetup", this.selectedArcherySetup.getId());
  176. }
  177. if (this.startAngle != null) {
  178. outState.putDouble("StartAngle", this.startAngle);
  179. }
  180. if (this.scHeVSSpinner.getSelectedItem() != null) {
  181. outState.putString("SelectedHeVS", this.scHeVSSpinner.getSelectedItem().toString());
  182. }
  183. }
  184. @Override
  185. protected void onRestoreInstanceState(final Bundle savedInstanceState) {
  186. super.onRestoreInstanceState(savedInstanceState);
  187. int selView = savedInstanceState.getInt("ViewFlipper.SelectedView", 0);
  188. this.viewFlipper.setDisplayedChild(selView);
  189. if (savedInstanceState.containsKey("SelectedArcherySetup")) {
  190. this.selectedArcherySetup = ArcherySetupDao.getInstance().loadById(savedInstanceState.getLong("SelectedArcherySetup"));
  191. }
  192. this.startAngle = savedInstanceState.getDouble("StartAngle");
  193. this.selectedHeVS = savedInstanceState.getString("SelectedHeVS");
  194. deactivateAllXTextView();
  195. switch (selView) {
  196. case 0:
  197. xTextViewUp(this.txtViewParams);
  198. break;
  199. case 1:
  200. xTextViewUp(this.txtViewResults);
  201. break;
  202. case 2:
  203. xTextViewUp(this.txtViewSight);
  204. break;
  205. default:
  206. break;
  207. }
  208. }
  209. private void initializeComponents() {
  210. this.viewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper);
  211. this.paramsScrollView = (ScrollView) findViewById(R.id.paramsScrollView);
  212. this.sightCfgScrollView = (ScrollView) findViewById(R.id.sightCfgScrollView);
  213. this.txtViewParams = (XTextView) findViewById(R.id.viewParams);
  214. this.txtViewResults = (XTextView) findViewById(R.id.viewResults);
  215. this.txtViewSight = (XTextView) findViewById(R.id.viewSight);
  216. this.arrowDiameterTxtFld = (TextView) findViewById(R.id.arrowDiameterTxtFld);
  217. this.arrowCwTxtFld = (TextView) findViewById(R.id.arrowCwTxtFld);
  218. this.arrowWeightTxtFld = (TextView) findViewById(R.id.arrowWeightTxtFld);
  219. this.bowPulloutTxtFld = (TextView) findViewById(R.id.bowPulloutTxtFld);
  220. this.arrowV0TxtFld = (TextView) findViewById(R.id.arrowV0TxtFld);
  221. this.hNATxtFld = (TextView) findViewById(R.id.hNAFld);
  222. this.nockRaisingTxtFld = (TextView) findViewById(R.id.nockRaisingFld);
  223. this.braceHeightTxtFld = (TextView) findViewById(R.id.braceHeightFld);
  224. this.airTemperatureTxtFld = (TextView) findViewById(R.id.airTemperatureTxtFld);
  225. this.airRelativeHumidityTxtFld = (TextView) findViewById(R.id.airRelativeHumidityTxtFld);
  226. this.shootingDistanzTxtFld = (TextView) findViewById(R.id.shootingDistanzTxtFld);
  227. this.arrowNockHeightTxtFld = (TextView) findViewById(R.id.arrowNockHeightTxtFld);
  228. this.targetCenterHeightTxtFld = (TextView) findViewById(R.id.targetCenterHeightTxtFld);
  229. this.calcTimeIntervalCboBox = (XSpinner) findViewById(R.id.deltaTimeCboBox);
  230. this.calcAccuracyCboBox = (XSpinner) findViewById(R.id.calcPrecisionCboBox);
  231. this.scRiserSpinner = (RiserSpinner) findViewById(R.id.scRiserSpinner);
  232. this.scVvisHTxtFld = (TextView) findViewById(R.id.scVvisHTxtFld);
  233. this.scVvisVTxtFld = (TextView) findViewById(R.id.scVvisVTxtFld);
  234. this.scSightSpinner = (SightSpinner) findViewById(R.id.scSightSpinner);
  235. this.scHeVSSpinner = (XSpinner) findViewById(R.id.scHeVSSpinner);
  236. this.scHeVSTxtFld = (TextView) findViewById(R.id.scHeVSTxtFld);
  237. this.scaVTxtFld = (TextView) findViewById(R.id.scaVTxtFld);
  238. this.scaHTxtFld = (TextView) findViewById(R.id.scaHTxtFld);
  239. this.scVertScaleRngTxtFld = (TextView) findViewById(R.id.scVertScaleRngTxtFld);
  240. this.scVertScaleMiddleTxtFld = (TextView) findViewById(R.id.scVertSkalaMiddleTxtFld);
  241. this.scEvSValue = (FontTextView) findViewById(R.id.scEvSValue);
  242. this.flightCurveTxtFld = (XTextView) findViewById(R.id.flightCurveTxtFld);
  243. this.calcSettingBtn = (Button) findViewById(R.id.scBtnCalc);
  244. }
  245. private void addRiserAndSightSpinnerListeners() {
  246. this.scRiserSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
  247. @Override
  248. public void onItemSelected(final AdapterView<?> parent, final View view, final int position,
  249. final long id) {
  250. IRiser riser = RBSMainActivity.this.scRiserSpinner.getSelectedRiser();
  251. if (riser.getId() != -999) {
  252. RBSMainActivity.this.scVvisHTxtFld.setText(DF.format(riser.getVVisH()));
  253. RBSMainActivity.this.scVvisVTxtFld.setText(DF.format(riser.getVVisV()));
  254. } else {
  255. RBSMainActivity.this.scVvisHTxtFld.setText("");
  256. RBSMainActivity.this.scVvisVTxtFld.setText("");
  257. }
  258. RBSMainActivity.this.scVvisHTxtFld.setEnabled(riser.getId() == -999);
  259. RBSMainActivity.this.scVvisVTxtFld.setEnabled(riser.getId() == -999);
  260. }
  261. @Override
  262. public void onNothingSelected(final AdapterView<?> parent) { }
  263. });
  264. this.scSightSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
  265. @Override
  266. public void onItemSelected(final AdapterView<?> parent, final View view, final int position,
  267. final long id) {
  268. ISight sight = RBSMainActivity.this.scSightSpinner.getSelectedSight();
  269. if (sight.getId() != -999) {
  270. List<String> listHeVis = new ArrayList<String>();
  271. String heVis = sight.getHeVis();
  272. StringTokenizer t = new StringTokenizer(heVis, ",");
  273. while (t.hasMoreTokens()) {
  274. listHeVis.add(t.nextToken());
  275. }
  276. RBSMainActivity.this.scHeVSTxtFld.setVisibility(View.INVISIBLE);
  277. RBSMainActivity.this.scHeVSTxtFld.setLayoutParams(new LinearLayout.LayoutParams(RBSMainActivity.this.scHeVSTxtFld
  278. .getLayoutParams().width,
  279. RBSMainActivity.this.scHeVSTxtFld
  280. .getLayoutParams().height, 0f));
  281. RBSMainActivity.this.scHeVSSpinner.setVisibility(View.VISIBLE);
  282. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(RBSMainActivity.this.scHeVSSpinner.getLayoutParams().width,
  283. RBSMainActivity.this.scHeVSSpinner.getLayoutParams().height,
  284. 1f);
  285. params.gravity = Gravity.FILL_VERTICAL;
  286. RBSMainActivity.this.scHeVSSpinner.setLayoutParams(params);
  287. RBSMainActivity.this.scHeVSSpinner.setAdapter(new FontArrayAdapter<String>(RBSMainActivity.this, R.layout.rbs_spinner,
  288. listHeVis, RBSMainActivity.this.scHeVSSpinner));
  289. if (RBSMainActivity.this.selectedHeVS == null) {
  290. if (RBSMainActivity.this.selectedArcherySetup != null
  291. && RBSMainActivity.this.selectedArcherySetup.getSight().getId() == sight.getId()) {
  292. RBSMainActivity.this.scHeVSSpinner.setSelectionByVal(DF.format(RBSMainActivity.this.selectedArcherySetup
  293. .getSightHorzSetting()));
  294. }
  295. } else {
  296. RBSMainActivity.this.scHeVSSpinner.setSelectionByVal(RBSMainActivity.this.selectedHeVS);
  297. }
  298. RBSMainActivity.this.scaVTxtFld.setText(DF.format(sight.getAV()));
  299. RBSMainActivity.this.scaHTxtFld.setText(DF.format(sight.getAH()));
  300. RBSMainActivity.this.scVertScaleRngTxtFld.setText(DF.format(sight.getVertSkalaRangeMin()) + "-"
  301. + DF.format(sight.getVertSkalaRangeMax()));
  302. } else {
  303. RBSMainActivity.this.scHeVSSpinner.setVisibility(View.INVISIBLE);
  304. RBSMainActivity.this.scHeVSSpinner.setLayoutParams(new LinearLayout.LayoutParams(RBSMainActivity.this.scHeVSSpinner
  305. .getLayoutParams().width,
  306. RBSMainActivity.this.scHeVSSpinner
  307. .getLayoutParams().height, 0f));
  308. RBSMainActivity.this.scHeVSTxtFld.setVisibility(View.VISIBLE);
  309. RBSMainActivity.this.scHeVSTxtFld.setLayoutParams(new LinearLayout.LayoutParams(RBSMainActivity.this.scHeVSTxtFld
  310. .getLayoutParams().width,
  311. RBSMainActivity.this.scHeVSTxtFld
  312. .getLayoutParams().height, 1f));
  313. RBSMainActivity.this.scHeVSSpinner.setAdapter(new FontArrayAdapter<String>(RBSMainActivity.this, R.layout.rbs_spinner,
  314. new ArrayList<String>(),
  315. RBSMainActivity.this.scHeVSSpinner));
  316. RBSMainActivity.this.scaVTxtFld.setText("");
  317. RBSMainActivity.this.scaHTxtFld.setText("");
  318. RBSMainActivity.this.scVertScaleRngTxtFld.setText("");
  319. }
  320. RBSMainActivity.this.scaVTxtFld.setEnabled(sight.getId() == -999);
  321. RBSMainActivity.this.scaHTxtFld.setEnabled(sight.getId() == -999);
  322. RBSMainActivity.this.scVertScaleRngTxtFld.setEnabled(sight.getId() == -999);
  323. }
  324. @Override
  325. public void onNothingSelected(final AdapterView<?> parent) { }
  326. });
  327. }
  328. private void addTouchListeners() {
  329. // Scrollview muss den Swipe selbst handeln
  330. this.paramsScrollView.setOnTouchListener(new OnTouchListener() {
  331. private float downX, downY, upX, upY;
  332. @Override
  333. public boolean onTouch(final View v, final MotionEvent event) {
  334. switch (event.getAction()) {
  335. case MotionEvent.ACTION_DOWN: {
  336. this.downX = event.getX();
  337. this.downY = event.getY();
  338. }
  339. case MotionEvent.ACTION_UP: {
  340. this.upX = event.getX();
  341. this.upY = event.getY();
  342. float deltaX = this.upX - this.downX;
  343. float deltaY = this.upY - this.downY;
  344. // swipe from right to left ?
  345. if (deltaX < 0 && Math.abs(deltaX) > MIN_DISTANCE && Math.abs(deltaY) < MIN_DISTANCE) {
  346. // set the required Animation type to ViewFlipper
  347. // The Next screen will come in form Right and current Screen will go OUT to Left
  348. RBSMainActivity.this.viewFlipper.setInAnimation(RBSMainActivity.this, R.anim.in_from_right);
  349. RBSMainActivity.this.viewFlipper.setOutAnimation(RBSMainActivity.this, R.anim.out_to_left);
  350. // Show The Next Screen
  351. RBSMainActivity.this.viewFlipper.showNext();
  352. deactivateXTextView(RBSMainActivity.this.txtViewParams);
  353. xTextViewUp(RBSMainActivity.this.txtViewResults);
  354. deactivateXTextView(RBSMainActivity.this.txtViewSight);
  355. }
  356. }
  357. }
  358. return false;
  359. }
  360. });
  361. // Scrollview muss den Swipe selbst handeln
  362. this.sightCfgScrollView.setOnTouchListener(new OnTouchListener() {
  363. private float downX, downY, upX, upY;
  364. @Override
  365. public boolean onTouch(final View v, final MotionEvent event) {
  366. switch (event.getAction()) {
  367. case MotionEvent.ACTION_DOWN: {
  368. this.downX = event.getX();
  369. this.downY = event.getY();
  370. }
  371. case MotionEvent.ACTION_UP: {
  372. this.upX = event.getX();
  373. this.upY = event.getY();
  374. float deltaX = this.upX - this.downX;
  375. float deltaY = this.upY - this.downY;
  376. // swipe from left to right?
  377. if (deltaX > 0 && Math.abs(deltaX) > MIN_DISTANCE && Math.abs(deltaY) < MIN_DISTANCE) {
  378. // set the required Animation type to ViewFlipper
  379. // The Next screen will come in form Right and current Screen will go OUT to Left
  380. RBSMainActivity.this.viewFlipper.setInAnimation(RBSMainActivity.this, R.anim.in_from_left);
  381. RBSMainActivity.this.viewFlipper.setOutAnimation(RBSMainActivity.this, R.anim.out_to_right);
  382. // Show The Next Screen
  383. RBSMainActivity.this.viewFlipper.showPrevious();
  384. deactivateXTextView(RBSMainActivity.this.txtViewSight);
  385. xTextViewUp(RBSMainActivity.this.txtViewResults);
  386. deactivateXTextView(RBSMainActivity.this.txtViewParams);
  387. }
  388. }
  389. }
  390. return false;
  391. }
  392. });
  393. // Touchlistener für die oberen 3 Tabs
  394. OnTouchListener tabListener = new OnTouchListener() {
  395. @Override
  396. public boolean onTouch(final View v, final MotionEvent event) {
  397. switch (event.getAction()) {
  398. case MotionEvent.ACTION_DOWN: {
  399. deactivateAllXTextView();
  400. xTextViewDown((XTextView) v);
  401. return true;
  402. }
  403. case MotionEvent.ACTION_UP: {
  404. RBSMainActivity.this.viewFlipper.setInAnimation(RBSMainActivity.this, R.anim.in_from_right);
  405. RBSMainActivity.this.viewFlipper.setOutAnimation(RBSMainActivity.this, R.anim.out_to_left);
  406. if (v == RBSMainActivity.this.txtViewParams) {
  407. if (RBSMainActivity.this.viewFlipper.getDisplayedChild() != 0) {
  408. RBSMainActivity.this.viewFlipper.setDisplayedChild(0);
  409. }
  410. } else if (v == RBSMainActivity.this.txtViewResults) {
  411. if (RBSMainActivity.this.viewFlipper.getDisplayedChild() != 1) {
  412. RBSMainActivity.this.viewFlipper.setDisplayedChild(1);
  413. }
  414. } else {
  415. if (RBSMainActivity.this.viewFlipper.getDisplayedChild() != 2) {
  416. RBSMainActivity.this.viewFlipper.setDisplayedChild(2);
  417. }
  418. }
  419. xTextViewUp((XTextView) v);
  420. return true;
  421. }
  422. }
  423. return false;
  424. }
  425. };
  426. // Touchlistener an Tabs anhängen
  427. this.txtViewParams.setOnTouchListener(tabListener);
  428. this.txtViewResults.setOnTouchListener(tabListener);
  429. this.txtViewSight.setOnTouchListener(tabListener);
  430. this.calcSettingBtn.setOnClickListener(new OnClickListener() {
  431. @Override
  432. public void onClick(final View v) {
  433. calculateSettings();
  434. }
  435. });
  436. }
  437. private void addValueChangeListeners() {
  438. this.arrowV0TxtFld.addTextChangedListener(new TextWatcher() {
  439. @Override
  440. public void onTextChanged(final CharSequence s, final int start, final int before, final int count) { }
  441. @Override
  442. public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) { }
  443. @Override
  444. public void afterTextChanged(final Editable s) {
  445. if (!RBSMainActivity.this.arrowV0TxtFld.getText().toString().isEmpty()
  446. && !RBSMainActivity.this.shootingDistanzTxtFld.getText().toString().isEmpty()) {
  447. calculateAndSetPerformantAccuracy(Double.valueOf(RBSMainActivity.this.arrowV0TxtFld.getText().toString()),
  448. Double.valueOf(RBSMainActivity.this.shootingDistanzTxtFld.getText().toString()));
  449. }
  450. }
  451. });
  452. this.shootingDistanzTxtFld.addTextChangedListener(new TextWatcher() {
  453. @Override
  454. public void onTextChanged(final CharSequence s, final int start, final int before, final int count) { }
  455. @Override
  456. public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) { }
  457. @Override
  458. public void afterTextChanged(final Editable s) {
  459. if (!RBSMainActivity.this.arrowV0TxtFld.getText().toString().isEmpty()
  460. && !RBSMainActivity.this.shootingDistanzTxtFld.getText().toString().isEmpty()) {
  461. calculateAndSetPerformantAccuracy(Double.valueOf(RBSMainActivity.this.arrowV0TxtFld.getText().toString()),
  462. Double.valueOf(RBSMainActivity.this.shootingDistanzTxtFld.getText().toString()));
  463. }
  464. }
  465. });
  466. }
  467. @Override
  468. public boolean onPrepareOptionsMenu(final Menu menu) {
  469. int size = menu.size();
  470. for (int i = size - 1; i >= 0; i--) {
  471. menu.removeItem(menu.getItem(i).getItemId());
  472. }
  473. if (this.showInfoMenu) {
  474. this.showInfoMenu = false;
  475. getMenuInflater().inflate(R.menu.rbs_info_menu, menu);
  476. } else {
  477. getMenuInflater().inflate(R.menu.rbs_main, menu);
  478. }
  479. return true;
  480. }
  481. @Override
  482. public boolean onOptionsItemSelected(final MenuItem item) {
  483. // Handle item selection
  484. switch (item.getItemId()) {
  485. case R.id.chooseConfiguration:
  486. showDialog(DLG_CHOOSE_ARCHERYSETUP);
  487. return true;
  488. case R.id.doCalculation:
  489. calculate();
  490. return true;
  491. case R.id.addConfiguration:
  492. Intent intent = new Intent(this, MainConfigurationActivity.class);
  493. startActivityForResult(intent, 1);
  494. return true;
  495. case R.id.moreItems:
  496. this.showInfoMenu = true;
  497. closeOptionsMenu();
  498. new Handler().post(new Runnable() {
  499. @Override
  500. public void run() {
  501. openOptionsMenu();
  502. }
  503. });
  504. return true;
  505. case R.id.itemAbout:
  506. showDialog(DLG_ABOUT);
  507. return true;
  508. default:
  509. return super.onOptionsItemSelected(item);
  510. }
  511. }
  512. @Override
  513. public boolean onTouchEvent(final MotionEvent touchevent) {
  514. switch (touchevent.getAction()) {
  515. // when user first touches the screen to swap
  516. case MotionEvent.ACTION_DOWN: {
  517. this.lastX = touchevent.getX();
  518. break;
  519. }
  520. case MotionEvent.ACTION_UP: {
  521. float currentX = touchevent.getX();
  522. // if right to left swipe on screen
  523. if (this.lastX > currentX) {
  524. if (this.viewFlipper.getDisplayedChild() == 2) {
  525. break;
  526. }
  527. // set the required Animation type to ViewFlipper
  528. // The Next screen will come in form Right and current Screen will go OUT to Left
  529. this.viewFlipper.setInAnimation(this, R.anim.in_from_right);
  530. this.viewFlipper.setOutAnimation(this, R.anim.out_to_left);
  531. // Show The Next Screen
  532. this.viewFlipper.showNext();
  533. } else if (this.lastX < currentX) { // if left to right swipe on screen
  534. // If no more View/Child to flip
  535. if (this.viewFlipper.getDisplayedChild() == 0) {
  536. break;
  537. }
  538. // set the required Animation type to ViewFlipper
  539. // The Next screen will come in form Left and current Screen will go OUT to Right
  540. this.viewFlipper.setInAnimation(this, R.anim.in_from_left);
  541. this.viewFlipper.setOutAnimation(this, R.anim.out_to_right);
  542. // Show the previous Screen
  543. this.viewFlipper.showPrevious();
  544. }
  545. deactivateAllXTextView();
  546. switch (this.viewFlipper.getDisplayedChild()) {
  547. case 0:
  548. xTextViewUp(this.txtViewParams);
  549. break;
  550. case 1:
  551. xTextViewUp(this.txtViewResults);
  552. break;
  553. case 2:
  554. xTextViewUp(this.txtViewSight);
  555. break;
  556. default:
  557. break;
  558. }
  559. break;
  560. }
  561. }
  562. return false;
  563. }
  564. private void xTextViewDown(final XTextView view) {
  565. view.setDrawborderColor(getResources().getColor(R.color.android_yellow_dark));
  566. view.setTextColor(getResources().getColor(R.color.android_yellow_dark));
  567. }
  568. private void xTextViewUp(final XTextView view) {
  569. view.setDrawborderColor(getResources().getColor(R.color.android_yellow));
  570. view.setTextColor(getResources().getColor(R.color.android_yellow));
  571. }
  572. private void deactivateXTextView(final XTextView view) {
  573. view.setDrawborderColor(getResources().getColor(R.color.white));
  574. view.setTextColor(getResources().getColor(R.color.white));
  575. }
  576. private void deactivateAllXTextView() {
  577. deactivateXTextView(this.txtViewParams);
  578. deactivateXTextView(this.txtViewResults);
  579. deactivateXTextView(this.txtViewSight);
  580. }
  581. @Override
  582. protected Dialog onCreateDialog(final int id) {
  583. return DialogFactory.createDialog(id, this);
  584. }
  585. @Override
  586. public void onArcherySetupDlgDismissed(final IArcherySetup archerySetup) {
  587. this.selectedArcherySetup = archerySetup;
  588. if (archerySetup != null && archerySetup.getId() != -999) {
  589. this.arrowDiameterTxtFld.setText(DF.format(archerySetup.getArrowDiameter()));
  590. this.arrowCwTxtFld.setText(DF.format(archerySetup.getArrowCw()));
  591. this.arrowWeightTxtFld.setText(DF.format(archerySetup.getArrowWeight()));
  592. this.bowPulloutTxtFld.setText(DF.format(archerySetup.getBowPullout()));
  593. this.arrowV0TxtFld.setText(DF.format(archerySetup.getArrowV0()));
  594. this.hNATxtFld.setText(DF.format(archerySetup.getHNA()));
  595. this.nockRaisingTxtFld.setText(DF.format(archerySetup.getNockRaising()));
  596. this.braceHeightTxtFld.setText(DF.format(archerySetup.getBraceHeight()));
  597. this.arrowNockHeightTxtFld.setText(DF_1.format(archerySetup.getArrowNockHeight()));
  598. this.targetCenterHeightTxtFld.setText(DF_1.format(archerySetup.getArrowCenterHeight()));
  599. this.calcTimeIntervalCboBox.setSelectionByVal(archerySetup.getDeltaTime().toString());
  600. this.calcAccuracyCboBox.setSelectionByVal(archerySetup.getCalcPrecision().toString());
  601. this.scRiserSpinner.setSelectedRiser(archerySetup.getRiser());
  602. this.scRiserSpinner.fireSelectionChangedEvent();
  603. this.scSightSpinner.setSelectedSight(archerySetup.getSight());
  604. this.scSightSpinner.fireSelectionChangedEvent();
  605. this.scVertScaleMiddleTxtFld.setText(DF.format(archerySetup.getSightVertSkalaMiddle()));
  606. this.airTemperatureTxtFld.setText(DEF_TEMP);
  607. this.airRelativeHumidityTxtFld.setText(DEF_HUMIDITY);
  608. this.shootingDistanzTxtFld.setText(DEF_DISTANCE);
  609. } else {
  610. this.arrowDiameterTxtFld.setText("");
  611. this.arrowDiameterTxtFld.setText("");
  612. this.arrowCwTxtFld.setText("");
  613. this.arrowWeightTxtFld.setText("");
  614. this.bowPulloutTxtFld.setText("");
  615. this.arrowV0TxtFld.setText("");
  616. this.hNATxtFld.setText("");
  617. this.nockRaisingTxtFld.setText("");
  618. this.braceHeightTxtFld.setText("");
  619. this.arrowNockHeightTxtFld.setText("");
  620. this.targetCenterHeightTxtFld.setText("");
  621. this.calcTimeIntervalCboBox.setSelectionByVal("");
  622. this.calcAccuracyCboBox.setSelectionByVal("");
  623. this.scRiserSpinner.setSelection(0);
  624. this.scRiserSpinner.fireSelectionChangedEvent();
  625. this.scSightSpinner.setSelection(0);
  626. this.scSightSpinner.fireSelectionChangedEvent();
  627. this.scVertScaleMiddleTxtFld.setText("");
  628. }
  629. }
  630. private boolean allParamFieldsValid() {
  631. return !this.arrowDiameterTxtFld.getText().toString().isEmpty()
  632. && !this.arrowCwTxtFld.getText().toString().isEmpty()
  633. && !this.arrowWeightTxtFld.getText().toString().isEmpty()
  634. && !this.bowPulloutTxtFld.getText().toString().isEmpty()
  635. && !this.arrowV0TxtFld.getText().toString().isEmpty()
  636. && !this.hNATxtFld.getText().toString().isEmpty()
  637. && !this.nockRaisingTxtFld.getText().toString().isEmpty()
  638. && !this.braceHeightTxtFld.getText().toString().isEmpty()
  639. && !this.airTemperatureTxtFld.getText().toString().isEmpty()
  640. && !this.airRelativeHumidityTxtFld.getText().toString().isEmpty()
  641. && !this.shootingDistanzTxtFld.getText().toString().isEmpty()
  642. && !this.arrowNockHeightTxtFld.getText().toString().isEmpty()
  643. && !this.targetCenterHeightTxtFld.getText().toString().isEmpty()
  644. && this.calcTimeIntervalCboBox.getSelectedItem() != null
  645. && this.calcAccuracyCboBox.getSelectedItem() != null
  646. && allSightParamFieldsValid();
  647. }
  648. private boolean allSightParamFieldsValid() {
  649. return !this.scVvisHTxtFld.getText().toString().isEmpty()
  650. && !this.scVvisVTxtFld.getText().toString().isEmpty()
  651. && !this.scaHTxtFld.getText().toString().isEmpty()
  652. && !this.scaVTxtFld.getText().toString().isEmpty()
  653. && !this.scVertScaleRngTxtFld.getText().toString().isEmpty()
  654. && ((this.scHeVSSpinner.getVisibility() == View.VISIBLE && this.scHeVSSpinner.getSelectedItem() != null)
  655. || (this.scHeVSTxtFld.getVisibility() == View.VISIBLE && !this.scHeVSTxtFld.getText().toString().isEmpty()))
  656. && !this.scVertScaleMiddleTxtFld.getText().toString().isEmpty();
  657. }
  658. /**
  659. * Startet die Berechnung wenn alle notwendigen Felder gefüllt sind.
  660. */
  661. private void calculate() {
  662. if (allParamFieldsValid()) {
  663. InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
  664. if (getCurrentFocus() != null) {
  665. imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
  666. }
  667. this.progressDialog = ProgressDialog.show(this, null, getResources().getString(R.string.caption_Calculating), true, false);
  668. CalculationTask calcTask = new CalculationTask();
  669. TrajectoryCalculator calculator = new TrajectoryCalculator(Double.valueOf(this.arrowDiameterTxtFld.getText().toString().trim()) * MILLI, //
  670. Double.valueOf(this.arrowCwTxtFld.getText().toString().trim()), //
  671. Double.valueOf(this.arrowWeightTxtFld.getText().toString().trim()) * MILLI, //
  672. Double.valueOf(this.arrowV0TxtFld.getText().toString().trim()), //
  673. Double.valueOf(this.shootingDistanzTxtFld.getText().toString().trim()), //
  674. Double.valueOf(this.targetCenterHeightTxtFld.getText().toString().trim())
  675. - Double.valueOf(this.arrowNockHeightTxtFld.getText().toString().trim()), //
  676. Double.valueOf(this.airTemperatureTxtFld.getText().toString().trim()), //
  677. Double.valueOf(this.airRelativeHumidityTxtFld.getText().toString().trim())
  678. * CENTI, //
  679. Double.valueOf(this.calcTimeIntervalCboBox.getSelectedItem().toString().trim()), //
  680. Double.valueOf(this.calcAccuracyCboBox.getSelectedItem().toString().trim())
  681. * CENTI, //
  682. this);
  683. calculator.setStartAngle(0d);
  684. calcTask.execute(calculator);
  685. } else {
  686. Toast toast = Toast.makeText(this, getResources().getString(R.string.caption_FillAllMandatoryFields), Toast.LENGTH_LONG);
  687. toast.setGravity(Gravity.CENTER, 0, 0);
  688. toast.show();
  689. }
  690. }
  691. @Override
  692. public void updateTrajectoryTxtFld(final Integer step, final Double[] flightCurveRow, final Double startAngle, final Double[] maxHCurve) {
  693. int width = this.flightCurveTxtFld.getMeasuredWidth();
  694. Double[] r1 = flightCurveRow;
  695. switch (step) {
  696. case 0:
  697. this.flightCurveTxtFld.setText("");
  698. this.flightCurveTxtFld.append(getResources().getString(R.string.fcChart_StartAngle) + DF_FC.format(startAngle) + " °\n\n");
  699. this.flightCurveTxtFld.append(getResources().getString(R.string.fcChart_MaxHeight) + DF_FC.format(maxHCurve[0])
  700. + " m / "
  701. + DF_FC.format(maxHCurve[0] + Double.valueOf(this.arrowNockHeightTxtFld.getText().toString().trim()))
  702. + " m, [t = " + DF_FC.format(maxHCurve[1]) + " s]\n\n");
  703. this.flightCurveTxtFld.append(getResources().getString(R.string.fcChart_FlightDuration)
  704. + DF_FC.format(r1[TrajectoryCalculator.IDX_T])
  705. + " sec\n\n");
  706. SpannableString line = new SpannableString("t [sec]\tVx [m/s]\tVy [m/s]\tx [m]\ty [m]\n\n");
  707. line.setSpan(new TabStopSpan.Standard(width / 5), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  708. line.setSpan(new TabStopSpan.Standard(width / 5 * 2), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  709. line.setSpan(new TabStopSpan.Standard(width / 5 * 3), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  710. line.setSpan(new TabStopSpan.Standard(width / 5 * 4), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  711. this.flightCurveTxtFld.append(line);
  712. break;
  713. case 1:
  714. line = new SpannableString(DF_FC.format(r1[TrajectoryCalculator.IDX_T]) + '\t'
  715. + DF_FC.format(r1[TrajectoryCalculator.IDX_VX]) + '\t'
  716. + DF_FC.format(r1[TrajectoryCalculator.IDX_VY]) + '\t'
  717. + DF_FC.format(r1[TrajectoryCalculator.IDX_X]) + '\t'
  718. + DF_FC.format(r1[TrajectoryCalculator.IDX_Y]) + "\n");
  719. line.setSpan(new TabStopSpan.Standard(width / 5), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  720. line.setSpan(new TabStopSpan.Standard(width / 5 * 2), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  721. line.setSpan(new TabStopSpan.Standard(width / 5 * 3), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  722. line.setSpan(new TabStopSpan.Standard(width / 5 * 4), 0, line.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  723. this.flightCurveTxtFld.append(line);
  724. break;
  725. default:
  726. break;
  727. }
  728. }
  729. @Override
  730. public void onCalculationDone(final Double[][] flightCurve, final Double startAngle, final Double[] maxHCurve) {
  731. this.startAngle = startAngle;
  732. updateFlightCurveChart(flightCurve);
  733. calculateSettings();
  734. if (this.progressDialog != null) {
  735. this.progressDialog.dismiss();
  736. }
  737. this.txtViewSight.doSingleTouch();
  738. }
  739. /**
  740. * @param flightCurve
  741. */
  742. private void updateFlightCurveChart(final Double[][] flightCurve) {
  743. XYSeries serie = new XYSeries(getApplicationContext().getResources().getString(R.string.fcChart_TitleLable));
  744. for (int i = 0; i < flightCurve.length; i++) {
  745. serie.add(flightCurve[i][TrajectoryCalculator.IDX_X], flightCurve[i][TrajectoryCalculator.IDX_Y]);
  746. }
  747. this.flightCurveChart.getDataSet().removeSeries(0);
  748. this.flightCurveChart.getDataSet().addSeries(0, serie);
  749. this.flightCurveChart.updateRendererAfterCalculation(flightCurve[flightCurve.length - 1][TrajectoryCalculator.IDX_X], flightCurve);
  750. }
  751. /**
  752. * Berechnet die definitve Visiereinstellung anhand des berechneten Flugbahnwinkels.
  753. */
  754. private void calculateSettings() {
  755. if (allSightParamFieldsValid() && this.selectedArcherySetup != null && this.startAngle != null) {
  756. Double x0;
  757. Double y0;
  758. Double x1;
  759. Double y1;
  760. Double x2;
  761. Double y2;
  762. Double x3;
  763. Double y3;
  764. Double r;
  765. Double s;
  766. Double vVh = Double.valueOf(this.scVvisHTxtFld.getText().toString()) + Double.valueOf(this.scaHTxtFld.getText().toString());
  767. Double vVv = Double.valueOf(this.scVvisVTxtFld.getText().toString()) + Double.valueOf(this.scaVTxtFld.getText().toString());
  768. Double a = Double.valueOf(this.bowPulloutTxtFld.getText().toString()) * 10;
  769. Double heVs = this.scHeVSSpinner.getVisibility() == View.VISIBLE ? Double.valueOf(this.scHeVSSpinner.getSelectedItem().toString())
  770. : Double.valueOf(this.scHeVSTxtFld.getText().toString());
  771. Double lhNA = this.selectedArcherySetup.getHNA();
  772. Double dltH = (Double.valueOf(this.targetCenterHeightTxtFld.getText().toString())
  773. - Double.valueOf(this.arrowNockHeightTxtFld.getText().toString())) * Math.pow(10, 3);
  774. Double ldistH = Double.valueOf(this.shootingDistanzTxtFld.getText().toString()) * Math.pow(10, 3);
  775. Double minSkala = this.scVertScaleRngTxtFld.getText().toString().contains("-")
  776. ? Double.valueOf(this.scVertScaleRngTxtFld.getText().toString().substring(0,
  777. this.scVertScaleRngTxtFld.getText().toString()
  778. .indexOf('-'))) : 0d;
  779. Double maxSkala = this.scVertScaleRngTxtFld.getText().toString().contains("-")
  780. ? Double.valueOf(this.scVertScaleRngTxtFld.getText().toString().substring(this.scVertScaleRngTxtFld.getText().toString()
  781. .indexOf('-') + 1,
  782. this.scVertScaleRngTxtFld.getText().toString()
  783. .length())) : 0d;
  784. Double nockRaising = Double.valueOf(this.nockRaisingTxtFld.getText().toString())
  785. - Double.valueOf(this.arrowDiameterTxtFld.getText().toString());
  786. Double braceHeight = Double.valueOf(this.braceHeightTxtFld.getText().toString());
  787. Double phi = -Math.atan(nockRaising / braceHeight); // Winkel des Pfeils zur Auflage infolge Nockpunktüberhöhung
  788. // PIN auf Höhe UK Vertikalskala Visier, gedreht um den Abschusswinkel...
  789. Double x01 = a * Math.cos(phi) + vVh + heVs;
  790. Double y01 = a * Math.sin(phi) + vVv - maxSkala / 2;
  791. x0 = Math.cos(Math.toRadians(this.startAngle)) * x01 - Math.sin(Math.toRadians(this.startAngle)) * y01;
  792. y0 = Math.sin(Math.toRadians(this.startAngle)) * x01 + Math.cos(Math.toRadians(this.startAngle)) * y01;
  793. // PIN auf Höhe Horizontalschlitten Visier, gedreht um den Abschusswinkel...
  794. Double x02 = a * Math.cos(phi) + vVh + heVs;
  795. Double y02 = a * Math.sin(phi) + vVv;
  796. x2 = Math.cos(Math.toRadians(this.startAngle)) * x02 - Math.sin(Math.toRadians(this.startAngle)) * y02;
  797. y2 = Math.sin(Math.toRadians(this.startAngle)) * x02 + Math.cos(Math.toRadians(this.startAngle)) * y02;
  798. // Schnittpunkt der Achse Horizontalschlitten Visier mit Achse Befestigungslöcher Visier, gedreht um den Abschusswinkel...
  799. Double x03 = a * Math.cos(phi) + vVh;
  800. Double y03 = a * Math.sin(phi) + vVv;
  801. x3 = Math.cos(Math.toRadians(this.startAngle)) * x03 - Math.sin(Math.toRadians(this.startAngle)) * y03;
  802. y3 = Math.sin(Math.toRadians(this.startAngle)) * x03 + Math.cos(Math.toRadians(this.startAngle)) * y03;
  803. // Unbekannte der Vektorgeradengleichung
  804. r = (lhNA * (x0 - x2) - x0 * y2 + x2 * y0) / (ldistH * (y0 - y2) + (dltH - lhNA) * (x2 - x0));
  805. s = -((ldistH * (lhNA - y0) + (dltH - lhNA) * x0) / (ldistH * (y0 - y2) + (dltH - lhNA) * (x2 - x0)));
  806. // Pin auf Visierlinie
  807. x1 = r * ldistH;
  808. y1 = lhNA + r * (dltH - lhNA);
  809. // Unten (+) oder oben (-) von (x2/y2) ?
  810. Double n = ((y2 - y3) * (x1 - x3) - (x2 - x3) * (y1 - y3)) < 0 ? -1.0 : 1.0;
  811. // Abstand P1 - P2
  812. Double d = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) * n;
  813. // Einstellung auf vert. Skala
  814. Double sV = Double.valueOf(this.scVertScaleMiddleTxtFld.getText().toString()) + d;
  815. this.scEvSValue.setText(DF_EVS.format(sV));
  816. if (minSkala <= sV && sV <= maxSkala) {
  817. this.scEvSValue.setBackgroundDrawable(getResources().getDrawable(R.drawable.evs_ok_background));
  818. } else {
  819. this.scEvSValue.setBackgroundDrawable(getResources().getDrawable(R.drawable.evs_nok_background));
  820. }
  821. } else {
  822. this.scEvSValue.setText("");
  823. Toast toast = Toast.makeText(this, getResources().getString(R.string.caption_FillAllMandatoryFields), Toast.LENGTH_LONG);
  824. toast.setGravity(Gravity.CENTER, 0, 0);
  825. toast.show();
  826. }
  827. }
  828. private void calculateAndSetPerformantAccuracy(final Double v0, final Double shootingDistance) {
  829. String[] calcAccuracies = getResources().getStringArray(R.array.CalculationTimeIntervals);
  830. String calcAccuracyToSet = calcAccuracies[calcAccuracies.length - 1];
  831. Double approxFlightTime = shootingDistance / v0;
  832. Double approxIntervalTime = approxFlightTime / MAX_TRAJ_POINTS;
  833. for (int i = 0; i < calcAccuracies.length - 1; i++) {
  834. Double accLow = Double.valueOf(calcAccuracies[i]);
  835. Double accHigh = Double.valueOf(calcAccuracies[i + 1]);
  836. if (accHigh < approxIntervalTime && approxIntervalTime <= accLow) {
  837. calcAccuracyToSet = calcAccuracies[i];
  838. break;
  839. }
  840. }
  841. this.calcTimeIntervalCboBox.setSelectionByVal(calcAccuracyToSet);
  842. }
  843. @Override
  844. protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
  845. super.onActivityResult(requestCode, resultCode, data);
  846. if (resultCode == 1) {
  847. loadRiserSpinner();
  848. loadSightSpinner();
  849. }
  850. }
  851. }