1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
package tim.prune.function.comparesegments;
import java.util.List;
import tim.prune.data.DataPoint;
import tim.prune.function.PointUtils;
/** Calculations dealing with time matching between the two segments */
class TimeCalculations
{
/** Placeholder class to get the information from a time match */
private static class TimeResult
{
private final IntersectionResult _firstResult;
private final IntersectionResult _resultBefore;
private final IntersectionResult _resultAfter;
private final double _fraction;
public TimeResult(IntersectionResult inFirst, IntersectionResult inBefore,
IntersectionResult inAfter, double inFraction)
{
_firstResult = inFirst;
_resultBefore = inBefore;
_resultAfter = inAfter;
_fraction = inFraction;
}
}
/**
* Find the position in the second segment which matches the time from the first segment
* @return the distance from the second segment (in radians), or null if no match was found
*/
public static Double findSecondDistanceAtSameTime(List<IntersectionResult> inResults, long inFirstSeconds)
{
TimeResult timeResult = findResultsAtSameTime(inResults, inFirstSeconds);
if (timeResult == null || timeResult._fraction < 0.0 || timeResult._fraction > 1.0) {
return null;
}
double distBeforeRadians = timeResult._resultBefore.getSecondDistanceRadians(timeResult._firstResult);
double spanRadians = timeResult._resultAfter.getSecondDistanceRadians(timeResult._firstResult) - distBeforeRadians;
if (spanRadians < 0.0) {
return null;
}
return distBeforeRadians + timeResult._fraction;
}
/**
* Find the position in the second segment which matches the time from the first segment
* @return a point from the second segment, or null if no match was found
*/
public static DataPoint findSecondPointAtSameTime(List<IntersectionResult> inResults, long inFirstSeconds)
{
TimeResult timeResult = findResultsAtSameTime(inResults, inFirstSeconds);
if (timeResult == null || timeResult._fraction < 0.0 || timeResult._fraction > 1.0) {
return null;
}
final DataPoint pointBefore = timeResult._resultBefore.getSecondPoint();
final DataPoint pointAfter = timeResult._resultAfter.getSecondPoint();
return PointUtils.interpolate(pointBefore, pointAfter, timeResult._fraction);
}
private static TimeResult findResultsAtSameTime(List<IntersectionResult> inResults, long inFirstSeconds)
{
IntersectionResult firstResult = null;
IntersectionResult latestBefore = null, earliestAfter = null;
long secsBefore = 0L, secsAfter = 0L;
for (IntersectionResult result : inResults)
{
final long duration2;
if (firstResult == null)
{
firstResult = result;
duration2 = 0L;
}
else {
duration2 = result.getSecondDurationSeconds(firstResult);
}
if (duration2 < inFirstSeconds)
{
if (latestBefore == null || (inFirstSeconds - duration2) < secsBefore) {
latestBefore = result;
secsBefore = inFirstSeconds - duration2;
}
}
else if (duration2 == inFirstSeconds) {
return new TimeResult(firstResult, result, result, 0.0);
}
else
{
if (earliestAfter == null || (duration2 - inFirstSeconds) < secsAfter)
{
earliestAfter = result;
secsAfter = duration2 - inFirstSeconds;
}
}
}
if (latestBefore == null || earliestAfter == null) {
return null;
}
double distBeforeRadians = latestBefore.getSecondDistanceRadians(firstResult);
double spanRadians = earliestAfter.getSecondDistanceRadians(firstResult) - distBeforeRadians;
if (spanRadians < 0.0) {
return null;
}
final long spanSeconds = earliestAfter.getSecondDurationSeconds(latestBefore);
return new TimeResult(firstResult, latestBefore, earliestAfter, 1.0 * secsBefore / spanSeconds);
}
}
|