private void ShowNearbySketches(SketchSample[] nearby, Point3D center3D, RayHitTestParameters cameraRay, Point center2D) { // Get a plane that is perpendicular to the look ray ITriangle plane = Math3D.GetPlane(center3D, cameraRay.Direction); // Project the points onto that plane var nearbyOnPlane = nearby. Select(o => new { Sketch = o, PlanePoint = Math3D.GetClosestPoint_Plane_Point(plane, o.Position) }). ToArray(); RotateTransform3D rotate = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new DoubleVector(cameraRay.Direction, _camera.UpDirection), new DoubleVector(new Vector3D(0, 0, -1), new Vector3D(0, 1, 0))))); // Lay these images down along the directions of the projected points // nearby is sorted by distance from the center image #region Attempt1 double halfLarge = SKETCHSIZE_LARGE / 2; double halfSmall = SKETCHSIZE_SMALL / 2; double stepDist = SKETCHSIZE_SMALL * .05; int startIncrement = Convert.ToInt32(Math.Floor((halfSmall + halfLarge) / stepDist)); List <Rect> existing = new List <Rect>(); existing.Add(new Rect(center2D.X - halfLarge, center2D.Y - halfLarge, SKETCHSIZE_LARGE, SKETCHSIZE_LARGE)); foreach (var nextSketch in nearbyOnPlane) { Vector direction = rotate.Transform(nextSketch.PlanePoint - center3D).ToVector2D(); Vector dirUnit = direction.ToUnit(); if (Math2D.IsInvalid(dirUnit)) { dirUnit = Math3D.GetRandomVector_Circular_Shell(1).ToVector2D(); } dirUnit = new Vector(dirUnit.X, -dirUnit.Y); Point point = new Point(); Rect rect = new Rect(); for (int cntr = startIncrement; cntr < 1000; cntr++) { point = center2D + (dirUnit * (stepDist * cntr)); rect = new Rect(point.X - halfSmall, point.Y - halfSmall, SKETCHSIZE_SMALL, SKETCHSIZE_SMALL); if (!existing.Any(o => o.IntersectsWith(rect))) { break; } } existing.Add(rect); //ShowImage(nextSketch.Sketch, center2D + (dirUnit * 100), false); ShowImage(nextSketch.Sketch, point, false); } #endregion }
private void ShowNearbySketches(Dot[] nearby, Point3D center3D, RayHitTestParameters cameraRay, Point center2D) { // Get a plane that is perpendicular to the look ray ITriangle plane = Math3D.GetPlane(center3D, cameraRay.Direction); // Project the points onto that plane var nearbyOnPlane = nearby. Select(o => new { Sketch = o, PlanePoint = Math3D.GetClosestPoint_Plane_Point(plane, o.Position) }). ToArray(); RotateTransform3D rotate = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new DoubleVector(cameraRay.Direction, _camera.UpDirection), new DoubleVector(new Vector3D(0, 0, -1), new Vector3D(0, 1, 0))))); // Lay these images down along the directions of the projected points // nearby is sorted by distance from the center image double halfLarge = SKETCHSIZE_LARGE / 2; double halfSmall = SKETCHSIZE_SMALL / 2; double stepDist = SKETCHSIZE_SMALL * .05; // Don't start counter at a distance of zero, that's just wasted steps. Figure out what cntr to use that is the distance of the two images touching int startIncrement = Convert.ToInt32(Math.Floor((halfSmall + halfLarge) / stepDist)); // Remember the locations of each image rect List <Rect> existing = new List <Rect>(); existing.Add(new Rect(center2D.X - halfLarge, center2D.Y - halfLarge, SKETCHSIZE_LARGE, SKETCHSIZE_LARGE)); foreach (var nextSketch in nearbyOnPlane) { // Get the 2D direction this sketch is from the main Vector direction = rotate.Transform(nextSketch.PlanePoint - center3D).ToVector2D(); Vector dirUnit = direction.ToUnit(true); if (Math2D.IsInvalid(dirUnit)) { dirUnit = Math3D.GetRandomVector_Circular_Shell(1).ToVector2D(); // sitting on top of each other, just push it in a random direction } dirUnit = new Vector(dirUnit.X, -dirUnit.Y); Point point = new Point(); Rect rect = new Rect(); // Keep walking along that direction until the rectangle doesn't intersect any existing sketches for (int cntr = startIncrement; cntr < 1000; cntr++) { point = center2D + (dirUnit * (stepDist * cntr)); rect = new Rect(point.X - halfSmall, point.Y - halfSmall, SKETCHSIZE_SMALL, SKETCHSIZE_SMALL); if (!existing.Any(o => o.IntersectsWith(rect))) { break; } } existing.Add(rect); ShowImage(nextSketch.Sketch, point, false); } }
/// <summary> /// This overload returns a point on the shape that is closest to the point passed in /// </summary> public Point3D?CastRay(Point3D point) { Point3D?retVal = null; switch (_shape) { case ShapeType.Line: #region Line retVal = Math3D.GetClosestPoint_Line_Point(_point, _direction, point); #endregion break; case ShapeType.Lines: #region Lines retVal = CastRay_LinesCircles(_lines, null, point); #endregion break; case ShapeType.Plane: #region Plane retVal = Math3D.GetClosestPoint_Plane_Point(_plane, point); #endregion break; case ShapeType.Circle: #region Circle retVal = Math3D.GetClosestPoint_Circle_Point(_plane, _point, _radius, point); #endregion break; case ShapeType.Circles: #region Circles retVal = CastRay_LinesCircles(null, _circles, point); #endregion break; case ShapeType.LinesCircles: #region LinesCircles retVal = CastRay_LinesCircles(_lines, _circles, point); #endregion break; case ShapeType.Cylinder: #region Cylinder retVal = Math3D.GetClosestPoint_Cylinder_Point(_point, _direction, _radius, point); #endregion break; case ShapeType.Sphere: #region Sphere retVal = Math3D.GetClosestPoint_Sphere_Point(_point, _radius, point); #endregion break; case ShapeType.Mesh: throw new ApplicationException("finish this"); case ShapeType.None: retVal = null; break; default: throw new ApplicationException("Unknown ShapeType: " + _shape.ToString()); } return(retVal); }
private void ShowNearbyPreviews(Dot[] nearby, Dot dot, RayHitTestParameters cameraRay, Point center2D) { #region previews, sizes int dotMinSize = Math.Min(dot.PreviewSize.X, dot.PreviewSize.Y); int minSize = dotMinSize; foreach (Dot nearDot in nearby) { EnsurePreviewGenerated(nearDot, _getPreview); minSize = Math1D.Min(minSize, nearDot.PreviewSize.X, nearDot.PreviewSize.Y); } double halfMin = minSize / 2d; double stepDist = halfMin * .05; #endregion #region project plane // Get a plane that is perpendicular to the look ray ITriangle plane = Math3D.GetPlane(dot.Position, cameraRay.Direction); // Project the points onto that plane var nearbyOnPlane = nearby. Select(o => new { Dot = o, PlanePoint = Math3D.GetClosestPoint_Plane_Point(plane, o.Position) }). ToArray(); RotateTransform3D rotate = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new DoubleVector(cameraRay.Direction, _camera.UpDirection), new DoubleVector(new Vector3D(0, 0, -1), new Vector3D(0, 1, 0))))); #endregion // Lay these previews down along the directions of the projected points // nearby is sorted by distance from the center image // Don't start counter at a distance of zero, that's just wasted steps. Figure out what cntr to use that is the distance of the two images touching int startIncrement = Convert.ToInt32(Math.Floor(((dotMinSize / 2d) + halfMin) / stepDist)); // Remember the locations of each image rect List <Rect> existing = new List <Rect>(); existing.Add(new Rect(center2D.X - (dot.PreviewSize.X / 2d), center2D.Y - (dot.PreviewSize.Y / 2d), dot.PreviewSize.X, dot.PreviewSize.Y)); foreach (var nextDot in nearbyOnPlane) { #region project dot plane // Get the 2D direction this sketch is from the main Vector direction = rotate.Transform(nextDot.PlanePoint - dot.Position).ToVector2D(); Vector dirUnit = direction.ToUnit(true); if (Math2D.IsInvalid(dirUnit)) { dirUnit = Math3D.GetRandomVector_Circular_Shell(1).ToVector2D(); // sitting on top of each other, just push it in a random direction } dirUnit = new Vector(dirUnit.X, -dirUnit.Y); #endregion #region find clear space Point point = new Point(); Rect rect = new Rect(); double halfX = nextDot.Dot.PreviewSize.X / 2d; double halfY = nextDot.Dot.PreviewSize.Y / 2d; // Keep walking along that direction until the rectangle doesn't intersect any existing sketches for (int cntr = startIncrement; cntr < 1000; cntr++) { point = center2D + (dirUnit * (stepDist * cntr)); rect = new Rect(point.X - halfX, point.Y - halfY, nextDot.Dot.PreviewSize.X, nextDot.Dot.PreviewSize.Y); if (!existing.Any(o => o.IntersectsWith(rect))) { break; } } existing.Add(rect); #endregion ShowPreview(nextDot.Dot, point); } }