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(); }
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 }; }
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; } } }
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; } } }
public void TestClone() { Coordinate c = new Coordinate(100.0, 200.0, 50.0); Coordinate clone = (Coordinate)c.Clone(); Assert.IsTrue(c.Equals3D(clone)); }