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;
        }
Esempio n. 2
0
        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();
        }