public static IEnumerable<Point3D> RepresentativeTrajectory(LineSegmentClustering.Cluster cluster, double minDensity, double gamma) { var representativeTrajectory = new List<Point3D>(); var averageDirectionVector = averageDirectionVectorOfCluster(cluster); var theta = averageDirectionVector.AngleTo(new Vector3D(1, 0, 0)); //var firstAndLast = cluster.lineSegments.Select(l => l.First()).Union(cluster.lineSegments.Select(l => l.Last())); // order by X' //firstAndLast = firstAndLast.Select(c => c.Vector.ToPoint3D().Rotate(new Vector3D(0, 0, 0), theta)).OrderBy(p => p.X); var cs = CoordinateSystem.RotateTo(new Vector3D(1, 0, 0).Normalize(), averageDirectionVector.Normalize()); /*var firstAndLastStructs = cluster.lineSegments.Select(ls => new { first = ls.First().Vector.ToPoint3D().Rotate(averageDirectionVector.Orthogonal, theta), last = ls.Last().Vector.ToPoint3D().Rotate(averageDirectionVector.Orthogonal, theta) });*/ var firstAndLastStructs = cluster.lineSegments.Select(ls => new { first = cs.Transform(ls.First().Vector.ToPoint3D()), last = cs.Transform(ls.Last().Vector.ToPoint3D()) }); var firstAndLastStructsOrdered = firstAndLastStructs.OrderBy(fl => fl.first.X); var firstAndLast = firstAndLastStructs.SelectMany(fl => new[] {fl.first, fl.last}).OrderBy(p => p.X); var u = cs.Transform(new Vector3D(1, 0, 0)); var y = u.AngleTo(averageDirectionVector); for (int i = 0; i < firstAndLast.Count(); i++) { Point3D point = firstAndLast.ElementAt(i); var hittingLineSegments = new List<Line3D>(); foreach (var linesegment in firstAndLastStructsOrdered) { if (linesegment.first.X <= point.X && linesegment.last.X >= point.X) { hittingLineSegments.Add(new Line3D(linesegment.first, linesegment.last)); } if (linesegment.first.X > point.Y) { break; } } if (hittingLineSegments.Count() >= minDensity) { var diff = point.X - firstAndLast.ElementAt(i - 1).X; if (diff >= gamma) { var avgCoord = averageCoordinate(hittingLineSegments, point, cs); avgCoord = avgCoord.Rotate(averageDirectionVector.Orthogonal, -theta); representativeTrajectory.Add(avgCoord); } } } return representativeTrajectory; }
static void Main() { //GenerateTrajFile(); TestDistanceFunctons(); var trajectories = TrajectoryFileUtils.readData(DATA_FILE, lineCount:20); Console.WriteLine ("Partitioning Phase"); var ls = trajectories.Where(t => t.Count > 0) .Select (t => Algorithm.ApproximateTrajectoryPartition (t)) .Where(l => l.Count() > 1) .ToList(); Console.WriteLine ("GroupingPhase"); var c = new LineSegmentClustering (ls); var clusters = c.GenerateCluster (); double gamma = 0; var r = clusters.Select(cl => RepresentativeTrajectoryGenerator.RepresentativeTrajectory(cl, 2.0d, gamma)).ToList(); Console.WriteLine("represented"); }
private static Vector3D averageDirectionVectorOfCluster(LineSegmentClustering.Cluster cluster) { var averageDirectionVector = new List<Vector3D>(); foreach(var lineSegment in cluster.lineSegments) { var directionVectors = lineSegment.Zip(lineSegment.Skip(1), (first, second) => second.Vector - first.Vector); averageDirectionVector.Add(directionVectors.Sum()/directionVectors.Count()); } return averageDirectionVector.Sum()/averageDirectionVector.Count(); }