public static Coordinate FindElement2(int[][] matrix, Coordinate origin, Coordinate dest, int x)
        {
            if (!origin.Inbounds(matrix) || !dest.Inbounds(matrix))
            {
                return null;
            }
            if (matrix[origin.row][origin.column] == x)
            {
                return origin;
            }
            else if (!origin.IsBefore(dest))
            {
                return null;
            }

            /* Set start to start of diagonal and end to the end of the diagonal. Since
             * the grid may not be square, the end of the diagonal may not equal dest.
             */
            Coordinate start = (Coordinate)origin.Clone();
            int diagDist = Math.Min(dest.row - origin.row, dest.column - origin.column);
            Coordinate end = new Coordinate(start.row + diagDist, start.column + diagDist);
            Coordinate p = new Coordinate(0, 0);

            /* Do binary search on the diagonal, looking for the first element greater than x */
            while (start.IsBefore(end))
            {
                p.SetToAverage(start, end);
                if (x > matrix[p.row][p.column])
                {
                    start.row = p.row + 1;
                    start.column = p.column + 1;
                }
                else {
                    end.row = p.row - 1;
                    end.column = p.column - 1;
                }
            }

            /* Split the grid into quadrants. Search the bottom left and the top right. */
            return PartitionAndSearch(matrix, origin, dest, start, x);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="errorType"></param>
 /// <param name="pt"></param>
 public TopologyValidationError(TopologyValidationErrorType errorType, Coordinate pt)
 {
     _errorType = errorType;
     if (pt != null)
         _pt = (Coordinate)pt.Clone();
 }
        public Coordinate Transform(Coordinate coordinate)
        {
            var xy = new[] { coordinate.X, coordinate.Y };
            double[] z = null;
            if (!coordinate.Z.Equals(Coordinate.NullOrdinate))
                z = new[] { coordinate.Z };

            Reproject.ReprojectPoints(xy, z, Source, Target, 0, 1);

            var ret = (Coordinate)coordinate.Clone();
            ret.X = xy[0];
            ret.Y = xy[1];
            if (z != null)
                ret.Z = z[0];

            return ret;
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="errorType"></param>
 /// <param name="pt"></param>
 public TopologyValidationError(TopologyValidationErrors errorType, Coordinate pt)
 {
     this.errorType = errorType;
     if(pt != null)
         this.pt = (Coordinate) pt.Clone();
 }
Пример #5
0
        private RaycastResult raycastChunk(Vector3 start, Vector3 end, Chunk c)
        {
            Vector3 actualStart = start, actualEnd = end;

            start -= new Vector3(c.X, c.Y, c.Z);
            end -= new Vector3(c.X, c.Y, c.Z);

            Coordinate startCoord = new Coordinate { X = (int)start.X, Y = (int)start.Y, Z = (int)start.Z };
            Coordinate endCoord = new Coordinate { X = (int)end.X, Y = (int)end.Y, Z = (int)end.Z };

            int dx = ((start.X < end.X) ? 1 : ((start.X > end.X) ? -1 : 0));
            int dy = ((start.Y < end.Y) ? 1 : ((start.Y > end.Y) ? -1 : 0));
            int dz = ((start.Z < end.Z) ? 1 : ((start.Z > end.Z) ? -1 : 0));

            float minx = startCoord.X, maxx = minx + 1.0f;
            float tx = ((start.X > end.X) ? (start.X - minx) : (maxx - start.X)) / Math.Abs(end.X - start.X);
            float miny = startCoord.Y, maxy = miny + 1.0f;
            float ty = ((start.Y > end.Y) ? (start.Y - miny) : (maxy - start.Y)) / Math.Abs(end.Y - start.Y);
            float minz = startCoord.Z, maxz = minz + 1.0f;
            float tz = ((start.Z > end.Z) ? (start.Z - minz) : (maxz - start.Z)) / Math.Abs(end.Z - start.Z);

            float deltatx = 1.0f / Math.Abs(end.X - start.X);
            float deltaty = 1.0f / Math.Abs(end.Y - start.Y);
            float deltatz = 1.0f / Math.Abs(end.Z - start.Z);

            Coordinate coord = startCoord.Clone();

            Direction normal = Direction.None;

            Direction xDirection = dx > 0 ? Direction.NegativeX : (dx < 0 ? Direction.PositiveX : Direction.None);
            Direction yDirection = dy > 0 ? Direction.NegativeY : (dy < 0 ? Direction.PositiveY : Direction.None);
            Direction zDirection = dz > 0 ? Direction.NegativeZ : (dz < 0 ? Direction.PositiveZ : Direction.None);

            for (; ; )
            {
                if ((coord.X >= 0 && coord.X < this.chunkSize
                    && coord.Y >= 0 && coord.Y < this.chunkSize
                    && coord.Z >= 0 && coord.Z < this.chunkSize)
                    && c.Data[coord.X, coord.Y, coord.Z] != null)
                {
                    Coordinate actualCoord = coord.Move(c.X, c.Y, c.Z);

                    // Found intersection

                    Vector3 ray = actualEnd - actualStart;

                    Vector3 norm = normal == Direction.None ? -Vector3.Normalize(ray) : normal.GetVector();

                    Vector3 planePosition = new Vector3(actualCoord.X + 0.5f, actualCoord.Y + 0.5f, actualCoord.Z + 0.5f) + norm * 0.5f;

                    return new RaycastResult { Coordinate = actualCoord, Normal = normal, Position = this.GetAbsolutePosition(actualStart + (ray * Vector3.Dot((planePosition - actualStart), norm) / Vector3.Dot(ray, norm))) };
                }

                if (tx <= ty && tx <= tz)
                {
                    if (coord.X == endCoord.X)
                        break;
                    tx += deltatx;
                    coord.X += dx;
                    normal = xDirection;
                }
                else if (ty <= tz)
                {
                    if (coord.Y == endCoord.Y)
                        break;
                    ty += deltaty;
                    coord.Y += dy;
                    normal = yDirection;
                }
                else
                {
                    if (coord.Z == endCoord.Z)
                        break;
                    tz += deltatz;
                    coord.Z += dz;
                    normal = zDirection;
                }
            }
            return new RaycastResult { Coordinate = null };
        }
Пример #6
0
        private IEnumerable<Chunk> rasterizeChunks(Vector3 startRelative, Vector3 endRelative)
        {
            // Adapted from PolyVox
            // http://www.volumesoffun.com/polyvox/documentation/library/doc/html/_raycast_8inl_source.html

            startRelative = (startRelative - new Vector3(this.minX, this.minY, this.minZ)) / this.chunkSize;
            endRelative = (endRelative - new Vector3(this.minX, this.minY, this.minZ)) / this.chunkSize;

            Coordinate startCoord = new Coordinate { X = (int)startRelative.X, Y = (int)startRelative.Y, Z = (int)startRelative.Z };
            Coordinate endCoord = new Coordinate { X = (int)endRelative.X, Y = (int)endRelative.Y, Z = (int)endRelative.Z };

            int dx = ((startRelative.X < endRelative.X) ? 1 : ((startRelative.X > endRelative.X) ? -1 : 0));
            int dy = ((startRelative.Y < endRelative.Y) ? 1 : ((startRelative.Y > endRelative.Y) ? -1 : 0));
            int dz = ((startRelative.Z < endRelative.Z) ? 1 : ((startRelative.Z > endRelative.Z) ? -1 : 0));

            float minx = startCoord.X, maxx = minx + 1.0f;
            float tx = ((startRelative.X > endRelative.X) ? (startRelative.X - minx) : (maxx - startRelative.X)) / Math.Abs(endRelative.X - startRelative.X);
            float miny = startCoord.Y, maxy = miny + 1.0f;
            float ty = ((startRelative.Y > endRelative.Y) ? (startRelative.Y - miny) : (maxy - startRelative.Y)) / Math.Abs(endRelative.Y - startRelative.Y);
            float minz = startCoord.Z, maxz = minz + 1.0f;
            float tz = ((startRelative.Z > endRelative.Z) ? (startRelative.Z - minz) : (maxz - startRelative.Z)) / Math.Abs(endRelative.Z - startRelative.Z);

            float deltatx = 1.0f / Math.Abs(endRelative.X - startRelative.X);
            float deltaty = 1.0f / Math.Abs(endRelative.Y - startRelative.Y);
            float deltatz = 1.0f / Math.Abs(endRelative.Z - startRelative.Z);

            Coordinate coord = startCoord.Clone();

            Direction xDirection = dx > 0 ? Direction.NegativeX : (dx < 0 ? Direction.PositiveX : Direction.None);
            Direction yDirection = dy > 0 ? Direction.NegativeY : (dy < 0 ? Direction.PositiveY : Direction.None);
            Direction zDirection = dz > 0 ? Direction.NegativeZ : (dz < 0 ? Direction.PositiveZ : Direction.None);

            for (; ; )
            {
                if (coord.X >= 0 && coord.X < this.maxChunks
                    && coord.Y >= 0 && coord.Y < this.maxChunks
                    && coord.Z >= 0 && coord.Z < this.maxChunks)
                    yield return this.chunks[coord.X, coord.Y, coord.Z];

                if (tx <= ty && tx <= tz)
                {
                    if (coord.X == endCoord.X)
                        break;
                    tx += deltatx;
                    coord.X += dx;
                }
                else if (ty <= tz)
                {
                    if (coord.Y == endCoord.Y)
                        break;
                    ty += deltaty;
                    coord.Y += dy;
                }
                else
                {
                    if (coord.Z == endCoord.Z)
                        break;
                    tz += deltatz;
                    coord.Z += dz;
                }
            }
        }
Пример #7
0
        private IEnumerable<Coordinate> rasterize(Vector3 start, Vector3 end, Coordinate startCoord, Coordinate endCoord)
        {
            // Adapted from PolyVox
            // http://www.volumesoffun.com/polyvox/documentation/library/doc/html/_raycast_8inl_source.html

            int dx = ((start.X < end.X) ? 1 : ((start.X > end.X) ? -1 : 0));
            int dy = ((start.Y < end.Y) ? 1 : ((start.Y > end.Y) ? -1 : 0));
            int dz = ((start.Z < end.Z) ? 1 : ((start.Z > end.Z) ? -1 : 0));

            float minx = startCoord.X, maxx = minx + 1.0f;
            float tx = ((start.X > end.X) ? (start.X - minx) : (maxx - start.X)) / Math.Abs(end.X - start.X);
            float miny = startCoord.Y, maxy = miny + 1.0f;
            float ty = ((start.Y > end.Y) ? (start.Y - miny) : (maxy - start.Y)) / Math.Abs(end.Y - start.Y);
            float minz = startCoord.Z, maxz = minz + 1.0f;
            float tz = ((start.Z > end.Z) ? (start.Z - minz) : (maxz - start.Z)) / Math.Abs(end.Z - start.Z);

            float deltatx = 1.0f / Math.Abs(end.X - start.X);
            float deltaty = 1.0f / Math.Abs(end.Y - start.Y);
            float deltatz = 1.0f / Math.Abs(end.Z - start.Z);

            Coordinate coord = startCoord.Clone();

            Direction normal = Direction.None;

            Direction xDirection = dx > 0 ? Direction.NegativeX : (dx < 0 ? Direction.PositiveX : Direction.None);
            Direction yDirection = dy > 0 ? Direction.NegativeY : (dy < 0 ? Direction.PositiveY : Direction.None);
            Direction zDirection = dz > 0 ? Direction.NegativeZ : (dz < 0 ? Direction.PositiveZ : Direction.None);

            for (; ; )
            {
                yield return coord;

                if (tx <= ty && tx <= tz)
                {
                    if (coord.X == endCoord.X)
                        break;
                    tx += deltatx;
                    coord.X += dx;
                    normal = xDirection;
                }
                else if (ty <= tz)
                {
                    if (coord.Y == endCoord.Y)
                        break;
                    ty += deltaty;
                    coord.Y += dy;
                    normal = yDirection;
                }
                else
                {
                    if (coord.Z == endCoord.Z)
                        break;
                    tz += deltatz;
                    coord.Z += dz;
                    normal = zDirection;
                }
            }
        }
Пример #8
0
 public void TestClone()
 {
     Coordinate c = new Coordinate(100.0, 200.0, 50.0);
     Coordinate clone = (Coordinate)c.Clone();
     Assert.IsTrue(c.Equals3D(clone));
 }