/// <summary> /// 2D plane space to 3D world space. /// Plane space is defined by a normal-frame from Point and Normal of the plane. /// </summary> public static M44d GetPlaneToWorld(this Plane3d self) { M44d.NormalFrame(self.Point, self.Normal, out M44d local2global, out M44d _); return(local2global); }
/// <summary> /// Projects a point onto the plane (shortest distance). /// </summary> public static V3d Project(this Plane3d plane, V3d p) => p - plane.Height(p) * plane.Normal;
public static bool IsNormalTo(this Plane3d plane, Ray3d ray) => ray.Direction.IsParallelTo(plane.Normal);
/// <summary> /// Transforms points from plane space to world space. /// </summary> public static V3d[] Unproject(this Plane3d plane, IEnumerable <V2d> points) { var local2global = plane.GetPlaneToWorld(); return(points.Select(x => local2global.TransformPos(x.XYO)).ToArray()); }
public bool HitsCylinder(Cylinder3d cylinder, double tmin, double tmax, ref RayHit3d hit) { var axisDir = cylinder.Axis.Direction.Normalized; // Vector Cyl.P0 -> Ray.Origin var op = Origin - cylinder.P0; // normal RayDirection - CylinderAxis var normal = Direction.Cross(axisDir); var unitNormal = normal.Normalized; // normal (Vec Cyl.P0 -> Ray.Origin) - CylinderAxis var normal2 = op.Cross(axisDir); var t = -normal2.Dot(unitNormal) / normal.Length; var radius = cylinder.Radius; if (cylinder.DistanceScale != 0) { // cylinder gets bigger, the further away it is var pnt = GetPointOnRay(t); var dis = V3d.Distance(pnt, this.Origin); radius = ((cylinder.Radius / cylinder.DistanceScale) * dis) * 2; } // between enitre rays (caps are ignored) var shortestDistance = Fun.Abs(op.Dot(unitNormal)); if (shortestDistance <= radius) { var s = Fun.Abs(Fun.Sqrt(radius.Square() - shortestDistance.Square()) / Direction.Length); var t1 = t - s; // first hit of Cylinder shell var t2 = t + s; // second hit of Cylinder shell if (t1 > tmin && t1 < tmax) { tmin = t1; } if (t2 < tmax && t2 > tmin) { tmax = t2; } hit.T = t1; hit.Point = GetPointOnRay(t1); // check if found point is outside of Cylinder Caps var bottomPlane = new Plane3d(cylinder.Circle0.Normal, cylinder.Circle0.Center); var topPlane = new Plane3d(cylinder.Circle1.Normal, cylinder.Circle1.Center); var heightBottom = bottomPlane.Height(hit.Point); var heightTop = topPlane.Height(hit.Point); // t1 lies outside of caps => find closest cap hit if (heightBottom > 0 || heightTop > 0) { hit.T = tmax; // intersect with bottom Cylinder Cap var bottomHit = HitsPlane(bottomPlane, tmin, tmax, ref hit); // intersect with top Cylinder Cap var topHit = HitsPlane(topPlane, tmin, tmax, ref hit); // hit still close enough to cylinder axis? var distance = cylinder.Axis.Ray3d.GetMinimalDistanceTo(hit.Point); if (distance <= radius && (bottomHit || topHit)) { return(true); } } else { return(true); } } hit.T = tmax; hit.Point = V3d.NaN; return(false); }
public static bool IsOrthogonalTo(this Plane3d p0, Plane3d p1) => p0.Normal.IsOrthogonalTo(p1.Normal);
public static bool ApproximateEquals(this Plane3d a, Plane3d b, double tolerance) => ApproximateEquals(a.Normal, b.Normal, tolerance) && ApproximateEquals(a.Distance, b.Distance, tolerance);
/// <summary> /// Transforms point from plane space to world space. /// </summary> public static V3d Unproject(this Plane3d plane, V2d point) { var local2global = plane.GetPlaneToWorld(); return(local2global.TransformPos(point.XYO)); }
public void Create(Plane3d plane) { CreateQuadric(plane); CreateHeuristic(); }
public bool Equals(Plane3d other) => Normal.Equals(other.Normal) && Distance.Equals(other.Distance);
public static bool IsOrthogonalTo(this Plane3d p0, Plane3d p1) { return(p0.Normal.IsOrthogonalTo(p1.Normal)); }
public static bool IsParallelTo(this Plane3d plane, Ray3d ray) { return(ray.Direction.IsOrthogonalTo(plane.Normal)); }
public static bool IsParallelTo(this Plane3d p0, Plane3d p1) { return(p0.Normal.IsParallelTo(p1.Normal)); }
/// <summary> /// Projects a point from world space to plane space (shortest distance). /// </summary> public static V2d ProjectToPlaneSpace(this Plane3d plane, V3d p) => plane.GetWorldToPlane().TransformPos(p).XY;
public static bool ApproximateEquals(this Plane3d a, Plane3d b) => ApproximateEquals(a, b, Constant <double> .PositiveTinyValue);
/// <summary> /// Projects points from world space to plane space (shortest distance). /// </summary> public static V2d[] ProjectToPlaneSpace(this Plane3d plane, V3d[] points) { var global2local = plane.GetWorldToPlane(); return(points.Map(p => global2local.TransformPos(p).XY)); }
public PlanePair3d(Plane3d plane0, Plane3d plane1) { Plane0 = plane0; Plane1 = plane1; }
/// <summary> /// Transforms points from plane space to world space. /// </summary> public static V3d[] Unproject(this Plane3d plane, V2d[] points) { var local2global = plane.GetPlaneToWorld(); return(points.Map(p => local2global.TransformPos(p.XYO))); }
public PlaneTriple3d(Plane3d plane0, Plane3d plane1, Plane3d plane2) { Plane0 = plane0; Plane1 = plane1; Plane2 = plane2; }
public static bool IsParallelTo(this Plane3d p0, Plane3d p1, double epsilon = 1e-6) => p0.Normal.IsParallelTo(p1.Normal, epsilon);
/// <summary> /// Returns a transformation of an orthonormal basis in Plane- to WorldSpace. /// </summary> public static Trafo3d GetPlaneSpaceTransform(this Plane3d self) => Trafo3d.FromNormalFrame(self.Point, self.Normal);
public static bool IsOrthogonalTo(this Ray3d ray, Plane3d plane) => ray.Direction.IsParallelTo(plane.Normal);
/// <summary> /// 3D world space to 2D plane space. /// Plane space is defined by a normal-frame from Point and Normal of the plane. /// </summary> public static M44d GetWorldToPlane(this Plane3d self) { M44d.NormalFrame(self.Point, self.Normal, out M44d _, out M44d global2local); return(global2local); }
public static bool IsParallelTo(this Plane3d p0, Plane3d p1) => p0.Normal.IsParallelTo(p1.Normal);
/// <summary> /// Projects a point onto the plane (shortest distance). /// </summary> public static V3d Project(this Plane3d plane, V3d p) { return(p - plane.Height(p) * plane.Normal); }