mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-01 18:03:59 +00:00
fixed a number of bugs in distance conversions; added first wind test case
This commit is contained in:
1 parent
a6981f0e75
commit
4e91095bb1
10 files changed
+87
-3
No files matched your search
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.base.Distance;
|
||||
import com.sap.sailing.domain.base.Position;
|
||||
import com.sap.sailing.domain.base.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.base.impl.NauticalMileDistance;
|
||||
|
||||
public class PositionTest {
|
||||
@Test
|
||||
@@ -41,6 +42,15 @@ public class PositionTest {
|
||||
assertEquals(225.0, p6.getBearingGreatCircle(p5).getDegrees(), 0.1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateTest() {
|
||||
Position p1 = new DegreePosition(0, 0);
|
||||
// now travel to 123° for 0.001 nautical miles (~ 1.852m)
|
||||
Position p2 = p1.translateGreatCircle(new DegreeBearingImpl(123), new NauticalMileDistance(0.001));
|
||||
assertEquals(123, p1.getBearingGreatCircle(p2).getDegrees(), 0.0000001);
|
||||
assertEquals(0.001, p1.getDistance(p2).getNauticalMiles(), 0.0000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTranslateGreatCircle() {
|
||||
Position p1 = new DegreePosition(49.2, 008.3);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
|
||||
|
||||
public class WindTest {
|
||||
@Test
|
||||
public void testSingleElementWindTrack() {
|
||||
WindTrack track = new WindTrackImpl(30000 /* 30s averaging interval */);
|
||||
DegreePosition pos = new DegreePosition(0, 0);
|
||||
Wind wind = new WindImpl(pos, new MillisecondsTimePoint(0), new KnotSpeedImpl(10, new DegreeBearingImpl(123)));
|
||||
track.add(wind);
|
||||
Wind estimate = track.getEstimatedWind(pos, new MillisecondsTimePoint(0));
|
||||
assertEquals(10, estimate.getKnots(), 0.000000001);
|
||||
assertEquals(123, estimate.getBearing().getDegrees(), 0.000000001);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public abstract class AbstractDistance implements Distance {
|
||||
|
||||
@Override
|
||||
public Speed inTime(long milliseconds) {
|
||||
return new KilometersPerHourSpeedImpl(getKilometers() / milliseconds * 3.6);
|
||||
return new KilometersPerHourSpeedImpl(getKilometers() * 1000. * 3600. / milliseconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,5 +15,10 @@ public abstract class AbstractSpeedImpl implements Speed {
|
||||
public int compareTo(Speed speed) {
|
||||
return getMetersPerSecond() > speed.getMetersPerSecond() ? 1 : getMetersPerSecond() == speed.getMetersPerSecond() ? 0 : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ""+getKnots()+"kn";
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -21,5 +21,10 @@ public abstract class AbstractSpeedWithBearingImpl extends AbstractSpeedImpl imp
|
||||
public Position travelTo(Position pos, TimePoint from, TimePoint to) {
|
||||
return pos.translateGreatCircle(getBearing(), this.travel(from, to));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString()+" to "+getBearing().getDegrees()+"°";
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@ public class NauticalMileDistance extends AbstractDistance {
|
||||
|
||||
@Override
|
||||
public double getCentralAngleDeg() {
|
||||
return getGeographicalMiles() * 60.;
|
||||
return getGeographicalMiles() / 60.;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
package com.sap.sailing.domain.tracking;
|
||||
|
||||
import com.sap.sailing.domain.base.Bearing;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Timed;
|
||||
|
||||
/**
|
||||
* Records a wind observation made at a certain position at a given time with an observed speed and a bearing.
|
||||
* Note that while nautically wind is usually specified in the direction it's coming <em>from</em>, for
|
||||
* computational purposes internally we measure the wind in the direction <em>to</em> which it blows.
|
||||
* Use {@link #getFrom} to get the "inverse" bearing.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface Wind extends Positioned, Timed, SpeedWithBearing {
|
||||
/**
|
||||
* Computes the inverse bearing telling the direction from where the wind blows.
|
||||
*/
|
||||
Bearing getFrom();
|
||||
}
|
||||
@@ -4,5 +4,7 @@ import com.sap.sailing.domain.base.Position;
|
||||
import com.sap.sailing.domain.base.TimePoint;
|
||||
|
||||
public interface WindTrack extends Track<Wind> {
|
||||
void add(Wind wind);
|
||||
|
||||
Wind getEstimatedWind(Position p, TimePoint at);
|
||||
}
|
||||
@@ -1,19 +1,27 @@
|
||||
package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.Bearing;
|
||||
import com.sap.sailing.domain.base.Position;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.TimePoint;
|
||||
import com.sap.sailing.domain.base.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedImpl;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
|
||||
public class WindImpl extends KnotSpeedImpl implements Wind {
|
||||
private final Position position;
|
||||
private final TimePoint timepoint;
|
||||
private final Bearing from;
|
||||
|
||||
public WindImpl(Position p, TimePoint at, SpeedWithBearing avgWindSpeed) {
|
||||
super(avgWindSpeed.getKnots(), avgWindSpeed.getBearing());
|
||||
this.position = p;
|
||||
this.timepoint = at;
|
||||
double fromDeg = getBearing().getDegrees() + 180;
|
||||
if (fromDeg > 360) {
|
||||
fromDeg -= 360;
|
||||
}
|
||||
from = new DegreeBearingImpl(fromDeg);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -26,4 +34,14 @@ public class WindImpl extends KnotSpeedImpl implements Wind {
|
||||
return timepoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bearing getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ""+getTimePoint()+": "+getKnots()+"kn from "+getFrom();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,11 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
|
||||
public WindTrackImpl(long millisecondsOverWhichToAverage) {
|
||||
this.millisecondsOverWhichToAverage = millisecondsOverWhichToAverage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Wind wind) {
|
||||
getInternalFixes().add(wind);
|
||||
}
|
||||
|
||||
private final TimePoint zeroSeconds = new MillisecondsTimePoint(0);
|
||||
private final TimePoint oneSecond = new MillisecondsTimePoint(1000);
|
||||
@@ -35,7 +40,7 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
|
||||
Position blownTo = p;
|
||||
int secondsCount = 0;
|
||||
for (Wind before : beforeSet.descendingSet()) {
|
||||
if (at.asMillis() - before.getTimePoint().asMillis() > millisecondsOverWhichToAverage) {
|
||||
if (at.asMillis() - before.getTimePoint().asMillis() < millisecondsOverWhichToAverage) {
|
||||
blownTo = blownTo.translateGreatCircle(before.getBearing(), before.travel(zeroSeconds, oneSecond));
|
||||
secondsCount++;
|
||||
} else {
|
||||
@@ -84,5 +89,9 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
|
||||
public int compareTo(Speed o) {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public Bearing getFrom() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user