/// <summary> /// Returns the point of intersection with the ray and the plane. /// </summary> /// <param name="ray"></param> /// <returns>Point(NaN, NaN, Nan) if the ray is parallel to the plane or the plane is behind the ray</returns> public bool IntersectionPoint(Ray ray, out Point3D intersectionPoint) { //Check to see if the plane and the ray are parallel, if so then //they will not intersect double d = Vector3D.DotProduct(this.Normal, ray.Direction); if ((d > -1e-12) && (d < 1e-12)) { intersectionPoint = new Point3D(double.NaN, double.NaN, double.NaN); return false; } // P = P0 + tV // P . N + d = 0 // // (P0 + tV) . N + d = 0 // P0 . N + tV . N + d = 0 // t = -(P0 . N + d) / V . N double t = -(Vector3D.DotProduct((Vector3D)ray.Origin, this.Normal) + this.D) / d; if (t < 0) { intersectionPoint = new Point3D(double.NaN, double.NaN, double.NaN); return false; } intersectionPoint = ray.Origin + t * ray.Direction; return true; }
private double IntersectsWithTriangle(Ray ray, Point3D p0, Point3D p1, Point3D p2) { Vector3D e1 = p1 - p0; Vector3D e2 = p2 - p0; Vector3D p = Vector3D.CrossProduct(ray.Direction, e2); double a = Vector3D.DotProduct(e1, p); if (MathHelper.IsZero(a)) { //The ray and the triangle are parallel, they will not cross return -1; } double f = 1.0 / a; Vector3D s = ray.Origin - p0; double u = f * Vector3D.DotProduct(s, p); if ((u < 0) || (u > 1)) { //Outside of the triangle return -1; } Vector3D q = Vector3D.CrossProduct(s, e1); double v = f * Vector3D.DotProduct(ray.Direction, q); if ((v < 0) || (u + v > 1)) { //Outside of the triangle return -1; } //Need to check the ray intersection is in the direction of the ray double t = f * Vector3D.DotProduct(e2, q); if (t < 0) { //Outside of the triangle return -1; } return t; }
public Ray GetRayPlane(double X, double Y) { Point3D pt1 = new Point3D(X, Y, -max_x); Point3D pt2 = new Point3D(X, Y, 0); Vector3D dir = pt2 - pt1; Ray ray = new Ray(pt1, dir); return ray; }
public Ray GetRay(double angle, double Z, Vector3D offset) { AxisAngleRotation3D myRotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), angle); RotateTransform3D myRotateTransform = new RotateTransform3D(myRotation); Point3D pt1 = myRotateTransform.Transform(new Point3D(-max_x, 0, Z) + offset); Point3D pt2 = myRotateTransform.Transform(new Point3D(0, 0, Z) + offset); Vector3D dir = pt2 - pt1; Ray ray = new Ray(pt1, dir); return ray; }
public IntersectionType GetIntersectionPlane(double X, double Y, out Point3D intersection) { IntersectionType ret = IntersectionType.E_OUT; intersection = new Point3D(); Ray[] rays = new Ray[4]; double x_offset = m_dFreza.X / 2; double y_offset = m_dFreza.Y / 2; rays[0] = GetRayPlane(X, Y + y_offset); rays[1] = GetRayPlane(X + x_offset, Y); rays[2] = GetRayPlane(X, Y - y_offset); rays[3] = GetRayPlane(X - x_offset, Y); Ray ray_base = GetRayPlane(X, Y); double dist = Double.MaxValue; for (int i = 0; i < m_Model3DGroup.Children.Count; i++) { GeometryModel3D model = m_Model3DGroup.Children[i] as GeometryModel3D; if (model == null || model == meshCubeModel) { continue; } MeshGeometry3D geometry = model.Geometry as MeshGeometry3D; if (geometry == null) { continue; } //if (!model.Bounds.Contains(new Point3D(X, Y, 0))) //{ // continue; //} ret = IntersectionType.E_NOTHING; Point3DCollection points = geometry.Positions; for (int j = 0; j < points.Count; j += 3) { for (int k = 0; k < rays.Length; k++) { double t = IntersectsWithTriangle(rays[k], points[j], points[j + 1], points[j + 2]); if (t < 0) { continue; } if (t < dist && t >= 0) { dist = t; } } } } if (dist >= 0) { intersection = ray_base.Origin + dist * ray_base.Direction; return IntersectionType.E_INTERSECTION; } return ret; }
public IntersectionType GetIntersection(double angle, double Z, out Point3D intersection) { IntersectionType ret = IntersectionType.E_OUT; intersection = new Point3D(); AxisAngleRotation3D myRotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), angle); RotateTransform3D myRotateTransform = new RotateTransform3D(myRotation); Ray[] rays = new Ray[4]; Vector3D offset = new Vector3D(0, -m_dFreza.Y/2, 0); rays[0] = GetRay(angle, Z, offset); offset = new Vector3D(0, m_dFreza.Y/2, 0); rays[1] = GetRay(angle, Z, offset); offset = new Vector3D(0, 0, -m_dFreza.Z/2); rays[2] = GetRay(angle, Z, offset); offset = new Vector3D(0, 0, m_dFreza.Z/2); rays[3] = GetRay(angle, Z, offset); offset = new Vector3D(0, 0, 0); Ray ray_base = GetRay(angle, Z, offset); double dist = -1; for (int i = 0; i < m_Model3DGroup.Children.Count; i++) { GeometryModel3D model = m_Model3DGroup.Children[i] as GeometryModel3D; if (model == null || model == meshCubeModel) { continue; } MeshGeometry3D geometry = model.Geometry as MeshGeometry3D; if (geometry == null) { continue; } if (!model.Bounds.Contains(new Point3D(0, 0, Z))) { continue; } ret = IntersectionType.E_NOTHING; Point3DCollection points = geometry.Positions; for (int j = 0; j < points.Count; j += 3) { if (points[j].Z > (Z+3) && points[j + 1].Z > (Z+3) && points[j + 2].Z > (Z+3)) { break; } if (points[j].Z < (Z - 3) && points[j + 1].Z < (Z - 3) && points[j + 2].Z < (Z - 3)) { continue; } for (int k = 0; k < rays.Length; k++) { double t = IntersectsWithTriangle(rays[k], points[j], points[j + 1], points[j + 2]); if (t < 0) { continue; } if (t > dist && t < max_x) { dist = t; } } } } if (dist >= 0) { intersection = ray_base.Origin + dist * ray_base.Direction; return IntersectionType.E_INTERSECTION; } return ret; }