public Normal3 Sample(Random random) { ISphere sphere = new UnitSphere(Position3.Origin); Normal3 direction = ((Direction3)sphere.SurfacePosition(random)).Normalized(); return(IDirection3.InSameClosedHemisphere(Orientation, direction) ? direction : -direction); }
/// <summary> The SBVH thinks it can get a better split </summary> /// <returns>A better or equal split than the normal BVH would</returns> protected override Split?GetSplit() { Split?bvhSplit = base.GetSplit(); // TODO: Introduce Alpha to just use regular split Split? sbvhSplit; IDirection3 size = Shape.BoundingBox.Size; if (size.X > size.Y && size.X > size.Z) { sbvhSplit = BestSpatialBinSplit(Normal3.UnitX, AxisAlignedPlane.X, v => v.X); } else if (size.Y > size.Z) { sbvhSplit = BestSpatialBinSplit(Normal3.UnitY, AxisAlignedPlane.Y, v => v.Y); } else { sbvhSplit = BestSpatialBinSplit(Normal3.UnitZ, AxisAlignedPlane.Z, v => v.Z); } if (bvhSplit == null) { return(sbvhSplit); } if (sbvhSplit == null) { return(bvhSplit); } float bvhSplitSAH = bvhSplit.SurfaceAreaHeuristic; float sbvhSplitSAH = sbvhSplit.SurfaceAreaHeuristic; return(bvhSplitSAH < sbvhSplitSAH ? bvhSplit : sbvhSplit); }
/// <summary> Get the best split for this node </summary> /// <returns>The best split for this BVH node</returns> protected virtual Split?GetSplit() { if (Bin && Items.Count > BinAmount) { IDirection3 size = Shape.BoundingBox.Size; if (size.X > size.Y && size.X > size.Z) { return(BestBinSplit(Normal3.UnitX, v => v.X)); } else if (size.Y > size.Z) { return(BestBinSplit(Normal3.UnitY, v => v.Y)); } else { return(BestBinSplit(Normal3.UnitZ, v => v.Z)); } } else { return(BestSweepSplit()); } }
public bool Contains(Normal3 sample) => IDirection3.InSameClosedHemisphere(Orientation, sample);
public double ProbabilityDensity(Normal3 sample) => Math.Abs(IDirection3.Dot(Orientation, sample));