Example #1
0
    static void CreateNew()
    {
        // Create the actual object
        GameObject newObject = new GameObject("Line");

        Mesh newMesh = new Mesh();

        newMesh.name = "Line mesh";

        MeshFilter newMeshFilter = newObject.AddComponent <MeshFilter>();

        newMeshFilter.mesh = newMesh;

        // Create mesh collider
        newObject.AddComponent <MeshCollider>();

        // Create mesh renderer
        newObject.AddComponent <MeshRenderer>();

        // Attach script
        UVLine newLineScript = newObject.AddComponent <UVLine>();

        newLineScript.start = new Vector2(0, 0);
        newLineScript.end   = new Vector2(10, 0);

        // Make this action undoable
        Undo.RegisterCreatedObjectUndo(newObject, "Create Line");

        // Select the new object
        Selection.objects = new GameObject[] { newObject };
        //Selection.activeTransform = gameObject.transform;
    }
        /// <summary>
        /// returns null if ray does not hit the line. When hit, returns the distance from the hit point
        /// </summary>
        /// <param name="line">Line barrier</param>
        /// <returns>distance of ray origins from the hit point along the ray direction</returns>
        public double?DistanceToForIsovist(UVLine line, double tolerance)
        {
            //checking if the lines intersect at all
            double vs = this.Direction.CrossProductValue(this.Origin - line.Start);
            double ve = this.Direction.CrossProductValue(this.Origin - line.End);

            if (vs * ve > -tolerance)
            {
                return(null);
            }
            //finding the intersection
            if (vs == 0)
            {
                return(this.Origin.DistanceTo(line.Start));
            }
            else if (ve == 0)
            {
                return(this.Origin.DistanceTo(line.End));
            }
            else
            {
                double _length = line.GetLength();
                vs = Math.Abs(vs);
                ve = Math.Abs(ve);
                double lengthFromStart = _length * vs / (vs + ve);
                UV     hitPoint        = line.FindPoint(lengthFromStart);
                return(this.Origin.DistanceTo(hitPoint));
            }
        }
Example #3
0
        public void VisualizeLine(UVLine line, double elevation)
        {
            SpatialAnalysis.Geometry.UV start = line.Start.Copy();
            SpatialAnalysis.Geometry.UV end   = line.End.Copy();
            unitConversion.Transform(start);
            unitConversion.Transform(end);
            using (Transaction t = new Transaction(OSM_FOR_REVIT.RevitDocument, "Draw Barriers"))
            {
                t.Start();
                FailureHandlingOptions failOpt = t.GetFailureHandlingOptions();
                failOpt.SetFailuresPreprocessor(new CurveDrawingWarningSwallower());
                t.SetFailureHandlingOptions(failOpt);
                Plane       p   = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, new XYZ(0, 0, elevation));
                SketchPlane skp = SketchPlane.Create(OSM_FOR_REVIT.RevitDocument, p);
                try
                {
                    XYZ  p1 = new XYZ(start.U, start.V, elevation);
                    XYZ  p2 = new XYZ(end.U, end.V, elevation);
                    Line l  = Line.CreateBound(p1, p2);
                    OSM_FOR_REVIT.RevitDocument.Create.NewModelCurve(l, skp);
                }
                catch (Exception e)
                { MessageBox.Show(e.Report()); }

                t.Commit();
            }
        }
        /// <summary>
        /// Determines if the ray intersects with a specified line.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns><c>true</c> if intersects, <c>false</c> otherwise.</returns>
        public bool Intersects(UVLine line, double tolerance = 0)
        {
            double vs = this.Direction.CrossProductValue(this.Origin - line.Start);
            double ve = this.Direction.CrossProductValue(this.Origin - line.End);

            if (vs * ve > tolerance)
            {
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// Detects the collision that occurs between two states
        /// </summary>
        /// <param name="previous">Previous state</param>
        /// <param name="current">Current state</param>
        /// <param name="buffer">Offset buffer which is the radius of the body</param>
        /// <param name="tolerance">Tolerance set by default to the main document's absolute tolerance factor</param>
        /// <returns>An instance of the collision which can be null</returns>
        public static ICollision GetCollision(CollisionAnalyzer previous, CollisionAnalyzer current, double buffer, double tolerance = OSMDocument.AbsoluteTolerance)
        {
            Trajectory        trajectory = new Trajectory(current.Location, previous.Location);
            List <ICollision> collisions = new List <ICollision>();

            UVLine     edgeBuffer1 = CollisionAnalyzer.OffsetLine(previous.Barrrier, previous.Location, buffer);
            ICollision collisionWithEdgeBuffer1 = new GetCollisionWithEdge(trajectory, edgeBuffer1);

            collisions.Add(collisionWithEdgeBuffer1);

            ICollision collisionWithPreviousBarrierEndPoint = new GetCollisionWithEndPoint(trajectory, previous.Barrrier.End, buffer);

            collisions.Add(collisionWithPreviousBarrierEndPoint);
            ICollision collisionWithPreviousBarrierStartPoint = new GetCollisionWithEndPoint(trajectory, previous.Barrrier.Start, buffer);

            collisions.Add(collisionWithPreviousBarrierStartPoint);

            if (!previous.Barrrier.Equals(current.Barrrier))
            {
                UVLine     edgeBuffer2 = CollisionAnalyzer.OffsetLine(current.Barrrier, previous.Location, buffer);
                ICollision collisionWithEdgeBuffer2 = new GetCollisionWithEdge(trajectory, edgeBuffer2);
                collisions.Add(collisionWithEdgeBuffer2);
                if (current.Barrrier.End != previous.Barrrier.End && current.Barrrier.End != previous.Barrrier.Start)
                {
                    ICollision collisionWithCurrentBarrierEndPoint = new GetCollisionWithEndPoint(trajectory, current.Barrrier.End, buffer);
                    collisions.Add(collisionWithCurrentBarrierEndPoint);
                }
                if (current.Barrrier.Start != previous.Barrrier.End && current.Barrrier.Start != previous.Barrrier.Start)
                {
                    ICollision collisionWithCurrentBarrierStartPoint = new GetCollisionWithEndPoint(trajectory, current.Barrrier.Start, buffer);
                    collisions.Add(collisionWithCurrentBarrierStartPoint);
                }
            }
            if (collisions.Count != 0)
            {
                collisions.Sort((a, b) => a.LengthToCollision.CompareTo(b.LengthToCollision));
                ICollision firstCollision = collisions[0];
                if (!double.IsInfinity(firstCollision.LengthToCollision))
                {
                    //if (double.IsNaN(firstCollision.TimeStepRemainderProportion))
                    //{
                    //    System.Windows.MessageBox.Show(double.NaN.ToString() + " caught!");
                    //    GetCollision(previous, current, buffer, tolerance);
                    //}
                    return(firstCollision);
                }
            }
            return(null);
        }
        //Offsets an edge towards a line
        private static UVLine OffsetLine(UVLine edge, UV location, double offset)
        {
            UV vector        = location - edge.Start;
            UV edgeDirection = edge.End - edge.Start;

            edgeDirection.Unitize();
            UV vt = edgeDirection * edgeDirection.DotProduct(vector);
            UV vp = vector - vt;

            vp.Unitize();
            UV start = edge.Start + vp * offset;
            UV end   = edge.End + vp * offset;

            return(new UVLine(start, end));
        }
        /// <summary>
        /// Creates an instance of the collision
        /// </summary>
        /// <param name="displacementTrajectory">Displacement Trajectory</param>
        /// <param name="bufferEdge">Barrier edge offseted according to buffer</param>
        /// <param name="tolerance">Tolerance by default set to the tolerance absolute value of the main document</param>
        public GetCollisionWithEdge(Trajectory displacementTrajectory, UVLine bufferEdge, double tolerance = OSMDocument.AbsoluteTolerance)
        {
            this.DisplacementTrajectory = displacementTrajectory;
            this.BufferDirection        = bufferEdge.End - bufferEdge.Start;
            double?t = this.DisplacementTrajectory.TrajectoryLine.Intersection(bufferEdge, this.DisplacementTrajectory.TrajectoryLength, tolerance);

            if (t == null)
            {
                this.LengthToCollision = double.PositiveInfinity;
                return;
            }

            this.CollisionPoint              = this.DisplacementTrajectory.TrajectoryLine.Start + t.Value * this.DisplacementTrajectory.TrajectoryNormalizedVector;
            this.LengthToCollision           = DisplacementTrajectory.TrajectoryLength - t.Value;
            this.TimeStepRemainderProportion = t.Value / this.DisplacementTrajectory.TrajectoryLength;
        }
        private void DrawJG_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                double y     = this.rootVertex.Point.V;
                Point  point = Mouse.GetPosition(this);
                UV     p     = new UV(point.X, point.Y);
                if (this._moveMode == MoveMode.Horizontally)
                {
                    point.Y = y;
                    p.V     = y;
                }

                foreach (JGVertex item in this.rootVertex.Connections)
                {
                    //create the UVLine
                    UVLine uvLine = new UVLine(this.rootVertex.Point.Copy(), item.Point);
                    //find the Line from the map
                    Line line = this.edge_line.Find(uvLine);
                    //clear the pair of UVLine and Line from the map
                    this.edge_line.Remove(uvLine);
                    //update the UVLine with deep copies of the endpoints
                    uvLine.Start = p.Copy();
                    uvLine.End   = item.Point.Copy();
                    //update the line
                    line.X1 = uvLine.Start.U;
                    line.Y1 = uvLine.Start.V;
                    line.X2 = uvLine.End.U;
                    line.Y2 = uvLine.End.V;
                    // Add the pair of UVLine and Line to the map
                    this.edge_line.Add(line, uvLine);
                }
                //updating the vertex and its mark
                this.vertex_mark.Remove(this.rootLine);
                this.rootVertex.Point = p;
                this.rootLine.X1      = point.X - this.lineThickness / 2;
                this.rootLine.X2      = point.X + this.lineThickness / 2;
                this.rootLine.Y1      = point.Y;
                this.rootLine.Y2      = point.Y;
                this.vertex_mark.Add(this.rootVertex, this.rootLine);
            }
            catch (Exception)
            {
                //MessageBox.Show("from mouse move event: \n" + error.Message);
            }
        }
        private INTPolygon excludedArea(UV center, double r, UVLine edge)
        {
            INTPolygon area = new INTPolygon();

            double ds = edge.Start.DistanceTo(center);
            double de = edge.End.DistanceTo(center);

            r = (r > ds) ? r : ds;
            r = (r > de) ? r : de;
            double R  = 1.43 * r; // somthing larger than Math.Sqrt(2)*r
            UV     os = edge.Start - center;

            os.Unitize();
            UV oe = edge.End - center;

            oe.Unitize();
            List <UV> pnts = new List <UV>();
            double    x    = oe.DotProduct(os);

            if (x == 0)
            {
                return(area);
            }
            else if (x >= 0)
            {
                pnts.Add(edge.Start);
                pnts.Add(center + os * R);
                pnts.Add(center + oe * R);
                pnts.Add(edge.End);
            }
            else // if (x<0)
            {
                UV om = (os + oe) / 2;
                om.Unitize();
                pnts.Add(edge.Start);
                pnts.Add(center + os * R);
                pnts.Add(center + om * R);
                pnts.Add(center + oe * R);
                pnts.Add(edge.End);
            }
            return(this.ConvertUVListToINTPolygon(pnts));
        }
        /// <summary>
        /// returns null if ray does not hit the line. When hit, returns the distance from the hit point
        /// </summary>
        /// <param name="hitPoint">Hit point on the barrier</param>
        /// <param name="line">Line barrier</param>
        /// <returns>distance of ray origins from the hit point along the ray direction</returns>
        public double?DistanceTo(UVLine line, ref UV hitPoint, double tolerance = 0.0001)
        {
            hitPoint = null;
            double?result = null;
            double vs     = this.Direction.CrossProductValue(this.Origin - line.Start);
            double ve     = this.Direction.CrossProductValue(this.Origin - line.End);

            if (vs * ve > tolerance)
            {
                return(null);
            }
            if (vs == 0)
            {
                result   = this.Origin.DistanceTo(line.Start);
                hitPoint = line.Start;
            }
            else if (ve == 0)
            {
                result   = this.Origin.DistanceTo(line.End);
                hitPoint = line.End;
            }
            else
            {
                double _length = line.GetLength();
                vs = Math.Abs(vs);
                ve = Math.Abs(ve);
                double lengthFromStart = _length * vs / (vs + ve);
                hitPoint = line.FindPoint(lengthFromStart);
                result   = this.Origin.DistanceTo(hitPoint);
            }
            if (result != null)
            {
                var hitDirection = hitPoint - this.Origin;
                if (hitDirection.DotProduct(this.Direction) < 0)
                {
                    result   = null;
                    hitPoint = null;
                }
            }
            return(result);
        }
 /// <summary>
 /// Finds the interval of a line at V direction
 /// </summary>
 /// <param name="line">A line to find the interval for</param>
 /// <returns>A new interval</returns>
 public static Interval LineVValues(UVLine line)
 {
     return(new Interval(line.Start.V, line.End.V));
 }
 /// <summary>
 /// Finds the interval of a line at U direction
 /// </summary>
 /// <param name="line">A line to find the interval for</param>
 /// <returns>A new interval</returns>
 public static Interval LineUValues(UVLine line)
 {
     return(new Interval(line.Start.U, line.End.U));
 }
Example #13
0
        /// <summary>
        /// Create the barrier buffer polygons around the edges of the walkable field using Minkowski addition
        /// </summary>
        /// <param name="barrierEnvironment"></param>
        /// <param name="offsetValue"></param>
        public void LoadAllBarriersOffseted(BIM_To_OSM_Base barrierEnvironment, double offsetValue)
        {
            //offetting all of the boundaries
            this.BarrierBuffers = barrierEnvironment.ExpandAllBarrierPolygons(offsetValue);
            // creating lines for the boundaries
            int edgeNum = 0;

            foreach (BarrierPolygon item in this.BarrierBuffers)
            {
                edgeNum += item.Length;
            }
            this.BarrierBufferEdges = new UVLine[edgeNum];
            edgeNum = 0;
            foreach (BarrierPolygon brr in this.BarrierBuffers)
            {
                for (int i = 0; i < brr.Length; i++)
                {
                    UVLine line = new UVLine(brr.PointAt(i), brr.PointAt(brr.NextIndex(i)));
                    this.BarrierBufferEdges[edgeNum] = line;
                    edgeNum++;
                }
            }
            // cleaning up the cells from previous settings
            foreach (Cell cell in this.Cells)
            {
                if (cell.BarrierBufferEdgeIndices == null)
                {
                    cell.BarrierBufferEdgeIndices = new HashSet <int>();
                }
                else
                {
                    cell.BarrierBufferEdgeIndices.Clear();
                }
                cell.BarrierBufferOverlapState = OverlapState.Outside;
                cell.BufferBarrierEndPoints    = null;
            }
            // loading the lines into the cells
            for (int i = 0; i < this.BarrierBufferEdges.Length; i++)
            {
                Index[] intersectingCellIndices = this.FindLineIndices(this.BarrierBufferEdges[i]);
                foreach (Index item in intersectingCellIndices)
                {
                    if (this.ContainsCell(item))
                    {
                        this.Cells[item.I, item.J].BarrierBufferEdgeIndices.Add(i);
                    }
                }
            }
            //loading edge end points into the cells
            foreach (BarrierPolygon polygon in this.BarrierBuffers)
            {
                foreach (UV point in polygon.BoundaryPoints)
                {
                    Cell cell = this.FindCell(point);
                    if (cell != null)
                    {
                        if (cell.BufferBarrierEndPoints == null)
                        {
                            cell.BufferBarrierEndPoints = new List <UV>();
                        }
                        cell.BufferBarrierEndPoints.Add(point);
                    }
                }
            }
            // setting the overlapping states of the cells that overlap
            foreach (Cell cell in this.Cells)
            {
                if (cell.BarrierBufferEdgeIndices.Count > 0)
                {
                    cell.BarrierBufferOverlapState = OverlapState.Overlap;
                }
            }
            HashSet <Index> edge = new HashSet <Index>();

            foreach (Cell item in this.Cells)
            {
                if (item.FieldOverlapState == OverlapState.Overlap)
                {
                    var index = this.FindIndex(item);
                    if (index.I == 0 || index.I == this.GridWidth - 1 ||
                        index.J == 0 || index.J == this.GridHeight - 1)
                    {
                    }
                    else
                    {
                        edge.Add(index);
                    }
                }
            }
            HashSet <Index> temp_edge = new HashSet <Index>();
            HashSet <Index> area      = new HashSet <Index>();

            area.UnionWith(edge);
            while (edge.Count != 0)
            {
                foreach (var item in edge)
                {
                    foreach (var neighbor in Index.Neighbors)
                    {
                        var next = item + neighbor;
                        if (this.ContainsCell(next))
                        {
                            if (!area.Contains(next))
                            {
                                if (this.Cells[next.I, next.J].FieldOverlapState == OverlapState.Inside &&
                                    this.Cells[next.I, next.J].BarrierBufferOverlapState != OverlapState.Overlap)
                                {
                                    temp_edge.Add(next);
                                }
                            }
                        }
                    }
                }
                edge.Clear();
                edge.UnionWith(temp_edge);
                area.UnionWith(temp_edge);
                temp_edge.Clear();
            }
            foreach (Index item in area)
            {
                this.Cells[item.I, item.J].BarrierBufferOverlapState = OverlapState.Inside;
            }
            edge.Clear();
            edge = null;
            temp_edge.Clear();
            temp_edge = null;
            area.Clear();
            area = null;
            for (int i = 0; i < this.GridWidth; i++)
            {
                for (int j = 0; j < this.GridHeight; j++)
                {
                    if (this.Cells[i, j].FieldOverlapState != OverlapState.Inside)
                    {
                        if (this.Cells[i, j].BarrierBufferOverlapState != OverlapState.Overlap)
                        {
                            this.Cells[i, j].BarrierBufferOverlapState = OverlapState.Inside;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Checks the existence of a line of sight between two points.
        /// </summary>
        /// <param name="origin">The origin.</param>
        /// <param name="target">The target.</param>
        /// <param name="barrierType">Type of the barrier.</param>
        /// <param name="cellularFloor">The cellular floor.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns><c>true</c> if visible, <c>false</c> otherwise.</returns>
        public static bool Visible(UV origin, UV target, BarrierType barrierType, CellularFloorBaseGeometry cellularFloor, double tolerance = OSMDocument.AbsoluteTolerance)
        {
            UV     direction = target - origin;
            double length    = direction.GetLength();

            direction /= length;
            Ray ray = new Ray(origin, direction, cellularFloor.Origin,
                              cellularFloor.CellSize, tolerance);

            while (ray.Length + tolerance < length)
            {
                Index index = ray.NextIndex(cellularFloor.FindIndex, tolerance);
                if (cellularFloor.ContainsCell(index))
                {
                    switch (barrierType)
                    {
                    case BarrierType.Visual:
                        if (cellularFloor.Cells[index.I, index.J].VisualOverlapState == OverlapState.Overlap)
                        {
                            foreach (int item in cellularFloor.Cells[index.I, index.J].VisualBarrierEdgeIndices)
                            {
                                double?distance = ray.DistanceToForIsovist(cellularFloor.VisualBarrierEdges[item], tolerance);
                                if (distance != null && distance.Value + tolerance < length)
                                {
                                    UVLine hitEdge = cellularFloor.VisualBarrierEdges[item];
                                    return(false);
                                }
                            }
                        }
                        break;

                    case BarrierType.Physical:
                        if (cellularFloor.Cells[index.I, index.J].PhysicalOverlapState == OverlapState.Overlap)
                        {
                            foreach (int item in cellularFloor.Cells[index.I, index.J].PhysicalBarrierEdgeIndices)
                            {
                                double?distance = ray.DistanceToForIsovist(cellularFloor.PhysicalBarrierEdges[item], tolerance);
                                if (distance != null && distance.Value + tolerance < length)
                                {
                                    UVLine hitEdge = cellularFloor.PhysicalBarrierEdges[item];
                                    return(false);
                                }
                            }
                        }
                        break;

                    case BarrierType.Field:
                        if (cellularFloor.Cells[index.I, index.J].FieldOverlapState == OverlapState.Overlap)
                        {
                            foreach (int item in cellularFloor.Cells[index.I, index.J].FieldBarrierEdgeIndices)
                            {
                                double?distance = ray.DistanceToForIsovist(cellularFloor.FieldBarrierEdges[item], tolerance);
                                if (distance != null && distance.Value + tolerance < length)
                                {
                                    UVLine hitEdge = cellularFloor.FieldBarrierEdges[item];
                                    return(false);
                                }
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            return(true);
        }