// Static function to find the intersection of two planes // If they are parallel, returns false and outputs an invalid line struct // Otherwise, returns true and outputs the line of intersection public static bool Intersect(Plane a, Plane b, out Line result) { Vec3 cross = Vec3.Cross(a.normal, b.normal); double magsq = cross.ComputeMagnitudeSquared(); if (magsq == 0) { // failure! planes did not intersect, or planes were equal result = new Line { direction = Vec3.Zero, origin = Vec3.Zero }; // not a valid line! return false; } double invmag = 1.0 / Math.Sqrt(magsq); Vec3 line_direction = cross * invmag; // using plane a to find intersection (also could try b?) Vec3 in_a_toward_edge = Vec3.Normalize(Vec3.Cross(a.normal, line_direction)); Vec3 point_in_a = a.normal * a.offset; double dist = b.PointDistance(point_in_a); // seems this number could be either the positive or negative of what we want... double unsigned_r = dist * invmag; Vec3 positive = point_in_a + in_a_toward_edge * unsigned_r; Vec3 negative = point_in_a - in_a_toward_edge * unsigned_r; // figure out which one is actually at the intersection (or closest to it) double positive_check = new Vec2 { x = a.PointDistance(positive), y = b.PointDistance(positive) }.ComputeMagnitudeSquared(); double negative_check = new Vec2 { x = a.PointDistance(negative), y = b.PointDistance(negative) }.ComputeMagnitudeSquared(); // and use that one as a point on the line (for the out value) Vec3 point_on_line; if (positive_check < negative_check) point_on_line = positive; else point_on_line = negative; // success! planes intersectedx result = new Line { origin = point_on_line, direction = line_direction }; return true; }
public double offset; // Distance from the plane to the origin #endregion Fields #region Methods public static double CheckEquality(Plane a, Plane b) { double magprodsq = a.normal.ComputeMagnitudeSquared() * b.normal.ComputeMagnitudeSquared(); // although the magnitude of the normals SHOULD be 1... maybe somebody did something funky double dot = Vec3.Dot(a.normal, b.normal); double aparallelness = 1.0 - Math.Sqrt((dot * dot) / magprodsq); // closer to parallel yields smaller values of this aparallelness *= aparallelness; double a_from_b = b.PointDistance(a.normal * a.offset); double b_from_a = a.PointDistance(b.normal * b.offset); Vec3 a_on_b = a.normal * (a.offset + a_from_b); Vec3 b_on_a = b.normal * (b.offset + b_from_a); double distsq1 = (a_on_b - b.normal * b.offset).ComputeMagnitudeSquared(); // coplanar --> same point double distsq2 = (b_on_a - a.normal * a.offset).ComputeMagnitudeSquared(); // coplanar --> same point return aparallelness + distsq1 + distsq1; }
// Finds the intersection of the line and plane, and returns true if there is one // If there is no intersection, or the line is entirely within the plane, it returns false and the output position is the origin of the line public static bool IntersectPlane(Line line, Plane plane, out Vec3 pos) { Vec3 dir = Vec3.Normalize(line.direction); double dir_dot = Vec3.Dot(ref dir, ref plane.normal); if (dir_dot == 0.0) { pos = line.origin; return false; } else { double origin_dot = Vec3.Dot(ref line.origin, ref plane.normal); double tti = (plane.offset - origin_dot) / dir_dot; pos = line.origin + dir * tti; return true; } }
public void ComputePlane() { plane = Plane.FromTriangleVertices(sourceVerts[0].position, sourceVerts[1].position, sourceVerts[2].position); }