Example #1
0
        /// <summary>
        /// Calculating the Dijkstra distance
        /// </summary>
        /// <returns></returns>
        public double GetAstarDistance(LocationTimeValue a, LocationTimeValue b, Mesh mesh)
        {
            double ret = 0;

            try
            {
                TemporalMesh = new Mesh(mesh);

                End = TemporalMesh.Vertices.OrderBy(x => GeographyHelper.EuclideanDistance(b, x)).First();

                for (int i = 0; i < TemporalMesh.Vertices.Count(); i++)
                {
                    //Preparing the mesh for distance storage
                    if (TemporalMesh.Vertices[i].Value.Count() == 1)
                    {
                        TemporalMesh.Vertices[i].Value.Add(0);
                    }
                    else if (TemporalMesh.Vertices[i].Value.Count() == 0)
                    {
                        TemporalMesh.Vertices[i].Value.AddRange(new List <double>()
                        {
                            0, 0
                        });
                    }

                    //Initializing the distances
                    TemporalMesh.Vertices[i].Value[0]  = double.PositiveInfinity;
                    TemporalMesh.Vertices[i].Value[1]  = End.GetEuclideanDistance(TemporalMesh.Vertices[i]);
                    TemporalMesh.Vertices[i].Neighbors = new List <LocationTimeValue>();
                    TemporalMesh.Vertices[i].IsActive  = false;
                }

                Start = TemporalMesh.Vertices.OrderBy(x => GeographyHelper.EuclideanDistance(a, x)).First();

                Start.Value[0] = 0;

                End = TemporalMesh.Vertices.OrderBy(x => GeographyHelper.EuclideanDistance(b, x)).First();

                if (Start.GetEuclideanDistance(End) == 0)
                {
                    return(0);
                }

                //Building the shortest path
                BuildShortestPathAstar();

                ret = ShortestPathCost;
            }
            catch
            {
            }

            return(ret);
        }
Example #2
0
        /// <summary>
        /// Building the shortest path
        /// </summary>
        /// <param name="list"></param>
        /// <param name="node"></param>
        private void BuildShortestPath(List <LocationTimeValue> list, LocationTimeValue node)
        {
            if (node.Neighbors.Count() == 0)
            {
                return;
            }

            LocationTimeValue nearestNeighbor = node.Neighbors.Where(x => x.Neighbors.Count > 0).First();

            list.Add(nearestNeighbor);

            ShortestPathLength += GeographyHelper.EuclideanDistance(nearestNeighbor, node);

            ShortestPathCost += GeographyHelper.EuclideanDistance(nearestNeighbor, node);

            nearestNeighbor.Neighbors.Remove(node);

            if (nearestNeighbor.Equals(Start))
            {
                return;
            }

            BuildShortestPath(list, nearestNeighbor);
        }
        /// <summary>
        /// Converts a hexahedron to a list of tetrahedons
        /// </summary>
        /// <returns></returns>
        public List <Cell> ToTetrahedons(Mesh mesh)
        {
            //return object
            List <Cell> ret = new List <Cell>();

            try
            {
                LocationTimeValue[] vert = GetVertices(mesh);

                CreateFaces(mesh);

                LocationTimeValue loc1 = vert[0];
                LocationTimeValue loc2 = vert.OrderByDescending(x => GeographyHelper.EuclideanDistance(x, loc1)).First();

                for (int i = 0; i < Faces.Count(); i++)
                {
                    Faces[i].Vertices.OrderBy(x => GeographyHelper.EuclideanDistance(x, Faces[i].Vertices[0]));

                    Tetrahedron tet = new Tetrahedron();
                    tet.Vertices = new List <int>()
                    {
                        mesh.Vertices.IndexOf(Faces[i].Vertices[0]),
                        mesh.Vertices.IndexOf(Faces[i].Vertices[1]),
                        mesh.Vertices.IndexOf(Faces[i].Vertices[2])
                    };

                    if (Faces[i].Vertices.Contains(loc1))
                    {
                        tet.Vertices.Add(mesh.Vertices.IndexOf(loc2));
                    }
                    else
                    {
                        tet.Vertices.Add(mesh.Vertices.IndexOf(loc1));
                    }

                    tet.CreateFaces(mesh);

                    tet          = new Tetrahedron();
                    tet.Vertices = new List <int>()
                    {
                        mesh.Vertices.IndexOf(Faces[i].Vertices[3]),
                        mesh.Vertices.IndexOf(Faces[i].Vertices[1]),
                        mesh.Vertices.IndexOf(Faces[i].Vertices[2])
                    };

                    if (Faces[i].Vertices.Contains(loc1))
                    {
                        tet.Vertices.Add(mesh.Vertices.IndexOf(loc2));
                    }
                    else
                    {
                        tet.Vertices.Add(mesh.Vertices.IndexOf(loc1));
                    }

                    tet.CreateFaces(mesh);

                    ret.Add(tet);
                }
            }
            catch
            {
                ret = new List <Cell>();
            }

            return(ret);
        }
        /// <summary>
        /// Computing the IDW data matrix
        /// </summary>
        public void ComputeIDW()
        {
            if (OriginalLocationValues.Count < 1)
            {
                DiscretizedLocationValues   = new List <LocationTimeValue <double> >();
                DiscretizedLocationVariance = new List <LocationTimeValue <double> >();
            }

            List <LocationTimeValue <double> > ret = new List <LocationTimeValue <double> >();
            double rmseSum = 0;

            try
            {
                //Doing discretization if not done yet
                if (!OriginalLocationValues.First().IsDiscretized)
                {
                    DiscretizedLocationValues   = new List <LocationTimeValue <double> >();
                    DiscretizedLocationVariance = new List <LocationTimeValue <double> >();
                    DiscretizeOriginalLocalLocationValuesIntoRegularGrid();
                }

                for (int i = 0; i < DiscretizedLocationValues.Count(); i++)
                {
                    double value     = 0;
                    double weightSum = 0;

                    //Calculating IDW values
                    for (int j = 0; j < OriginalLocationValues.Count(); j++)
                    {
                        double dist = GeographyHelper.EuclideanDistance(DiscretizedLocationValues[i].X - OriginalLocationValues[j].X, DiscretizedLocationValues[i].Y - OriginalLocationValues[j].Y, DiscretizedLocationValues[i].Z - OriginalLocationValues[j].Z, false);
                        if (dist != 0)
                        {
                            //Summing up the weights
                            weightSum += 1 / Math.Pow(dist, Power);
                            //Increasing the value by the constrain value and it's weight
                            value += Convert.ToDouble(OriginalLocationValues[j].Value) / Math.Pow(dist, Power);
                        }
                        else
                        {
                            value = OriginalLocationValues[j].Value;
                            break;
                        }
                    }

                    DiscretizedLocationValues[i].Value = value / weightSum;
                }

                //Calculating the RMSE
                for (int i = 0; i < OriginalLocationValues.Count(); i++)
                {
                    double weightSum = 0;
                    double value     = 0;

                    for (int j = 0; j < OriginalLocationValues.Count(); j++)
                    {
                        if (i != j)
                        {
                            double dist = GeographyHelper.EuclideanDistance(DiscretizedLocationValues[i].X - OriginalLocationValues[j].X, DiscretizedLocationValues[i].Y - OriginalLocationValues[j].Y, DiscretizedLocationValues[i].Z - OriginalLocationValues[j].Z, false);
                            if (dist != 0)
                            {
                                weightSum += 1 / Math.Pow(dist, Power);
                                value     += Convert.ToDouble(OriginalLocationValues[j].Value) / Math.Pow(dist, Power);
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }

                    rmseSum += Math.Abs(Math.Pow(OriginalLocationValues[i].Value - (value / weightSum), 2));
                }

                RMSE = Math.Sqrt(rmseSum / OriginalLocationValues.Count());
            }
            catch
            {
            }
        }
Example #5
0
        /// <summary>
        /// Triangulates a surface
        /// </summary>
        /// <param name="points"></param>
        /// <returns></returns>
        public List <Face> TriangulateSurface(List <LocationTimeValue> inputVertices)
        {
            List <Face> mesh = new List <Face>();

            try
            {
                // Important! Sort the list so that points sweep from left - right
                inputVertices.Sort();

                SqlGeometry MultiPoint = inputVertices.ToSqlGeometry();

                // Calculate the "supertriangle" that encompasses the pointset
                SqlGeometry Envelope = MultiPoint.STEnvelope();

                // Width
                double dx = (double)(Envelope.STPointN(2).STX - Envelope.STPointN(1).STX);

                // Height
                double dy = (double)(Envelope.STPointN(4).STY - Envelope.STPointN(1).STY);

                // Maximum dimension
                double dmax = (dx > dy) ? dx : dy;

                // Centre
                double avgx = (double)Envelope.STCentroid().STX;
                double avgy = (double)Envelope.STCentroid().STY;

                // Create the points at corners of the supertriangle
                LocationTimeValue a = new LocationTimeValue(avgx - 2 * dmax, avgy - dmax);
                LocationTimeValue b = new LocationTimeValue(avgx + 2 * dmax, avgy - dmax);
                LocationTimeValue c = new LocationTimeValue(avgx, avgy + 2 * dmax);

                Triangle superTriangle = new Triangle(a, b, c);

                List <Triangle> Triangles = new List <Triangle>();
                Triangles.Add(superTriangle);


                // Loop through each point
                Parallel.For(0, inputVertices.Count(), i =>
                {
                    // Initialise the edge buffer
                    List <LocationTimeValue[]> Edges = new List <LocationTimeValue[]>();

                    try
                    {
                        // Loop through each triangle
                        for (int j = Triangles.Count - 1; j >= 0; j--)
                        {
                            // If the point lies within the circumcircle of this triangle
                            if (GeographyHelper.EuclideanDistance(Triangles[j].GetCircumCentre(), inputVertices[i]) <= Triangles[j].GetRadius())
                            {
                                // Add the triangle edges to the edge buffer
                                Edges.Add(new LocationTimeValue[] { Triangles[j].Vertices[0], Triangles[j].Vertices[1] });
                                Edges.Add(new LocationTimeValue[] { Triangles[j].Vertices[1], Triangles[j].Vertices[2] });
                                Edges.Add(new LocationTimeValue[] { Triangles[j].Vertices[2], Triangles[j].Vertices[0] });

                                // Remove this triangle from the list
                                Triangles.RemoveAt(j);
                            }

                            // If this triangle is complete
                            else if (inputVertices[i].X >= Triangles[j].GetCircumCentre().X + Triangles[j].GetRadius())
                            {
                                mesh.Add(Triangles[j]);
                                Triangles.RemoveAt(j);
                            }
                        }

                        // Remove duplicate edges
                        for (int j = Edges.Count - 1; j > 0; j--)
                        {
                            for (int k = j - 1; k >= 0; k--)
                            {
                                // Compare if this edge match in either direction
                                if (Edges[j][0].Equals(Edges[k][1]) && Edges[j][1].Equals(Edges[k][0]))
                                {
                                    // Remove both duplicates
                                    Edges.RemoveAt(j);
                                    Edges.RemoveAt(k);

                                    // We've removed an item from lower down the list than where j is now, so update j
                                    j--;
                                    break;
                                }
                            }
                        }

                        // Create new triangles for the current point
                        for (int j = 0; j < Edges.Count; j++)
                        {
                            Triangle T = new Triangle(Edges[j][0], Edges[j][1], inputVertices[i]);
                            Triangles.Add(T);
                        }
                    }
                    catch
                    {
                    }
                });

                mesh.AddRange(Triangles);

                int count = mesh.Count();

                //We've finished triangulation. Move any remaining triangles onto the completed list
                for (int i = 0; i < count; i++)
                {
                    if (mesh[i].Vertices.Any(x => superTriangle.Vertices.Contains(x)))
                    {
                        mesh.RemoveAt(i);
                        count--;
                        i--;
                    }
                }
            }
            catch
            {
            }


            return(mesh);
        }
Example #6
0
        /// <summary>
        /// Performing a A* search
        /// </summary>
        private void AstarSearch()
        {
            NodeVisits = 0;

            //Initializing priority queue
            var prioQueue = new List <LocationTimeValue>();

            //Adding start point to the queue
            prioQueue.Add(Start);

            //Filling priority queue and iterating through it until break conditions are met
            do
            {
                NodeVisits++;

                //Order points by distance to start
                prioQueue = prioQueue.OrderBy(x => x.Value[0] + x.Value[1]).ToList();

                var node = prioQueue.First();

                prioQueue.Remove(node);

                //Getting the neighbors of the node
                var neighbors = TemporalMesh.GetNeighbors(node).Result.OrderBy(x => GeographyHelper.EuclideanDistance(x, node)).ToList();

                //Iterating over the neighbors and detect which one has the lowest distance to the node
                for (int i = 0; i < neighbors.Count(); i++)
                {
                    //Check that the point does not equals the node where we came from
                    if (node.Neighbors.Count > 0)
                    {
                        if (neighbors[i].Equals(node.Neighbors.First()))
                        {
                            continue;
                        }
                    }

                    //Determining the euclidean distance to the neighbor
                    double dist = GeographyHelper.EuclideanDistance(neighbors[i], node);

                    neighbors[i].Value[0] = node.Value[0] + dist;

                    if (neighbors[i].Neighbors.Count == 0 || !neighbors.Where(x => !x.Equals(node)).Any(x => x.Value[0] < neighbors[i].Value[0]))
                    {
                        //Setting the node as a neighbor
                        neighbors[i].Neighbors.Clear();
                        neighbors[i].Neighbors.Add(node);

                        //If the node equals the end, we reached our aim
                        if (node.Equals(End))
                        {
                            return;
                        }

                        //Adding node to the priority queue
                        if (!prioQueue.Contains(neighbors[i]))
                        {
                            prioQueue.Add(neighbors[i]);
                        }
                    }
                }

                //"Deactivating" the node that it will not be used again
                node.IsActive = true;
            } while (prioQueue.Any());
        }