/// <summary>
/// Луч в направлении direction пересекает габариты. на самом деле строятся другие габариты в плоскости Plane(picked, direction).
/// При пустом direction вызывате IsInside
/// </summary>
public static bool IsIntersect(this Point3d picked, Vector3d direction, Extents3d ext)
{
if (direction == new Vector3d()) // считаем что все происходит в плоскости XY
return picked.IsInside(ext);
// все вершины прямоугольника заданного Extents3d
Point3d[] extPoints = new Point3d[]{
ext.MinPoint,
new Point3d(ext.MaxPoint.X, ext.MinPoint.Y, ext.MinPoint.Z),
new Point3d(ext.MinPoint.X, ext.MaxPoint.Y, ext.MinPoint.Z),
new Point3d(ext.MinPoint.X, ext.MinPoint.Y, ext.MaxPoint.Z),
new Point3d(ext.MaxPoint.X, ext.MaxPoint.Y, ext.MinPoint.Z),
new Point3d(ext.MaxPoint.X, ext.MinPoint.Y, ext.MaxPoint.Z),
new Point3d(ext.MinPoint.X, ext.MaxPoint.Y, ext.MaxPoint.Z),
ext.MaxPoint
};
// процирование всех вершин на плоскость перпендикулярную direction и поиск габаритов этого множества точек
double minX = double.PositiveInfinity, minY = double.PositiveInfinity, minZ = double.PositiveInfinity;
double maxX = double.NegativeInfinity, maxY = double.NegativeInfinity, maxZ = double.NegativeInfinity;
using (Plane pl = new Plane(picked, direction))
foreach (Point3d p in extPoints)
{
Point3d proj = p.Project(pl, direction);
if (proj.X < minX) minX = proj.X;
else if (proj.X > maxX) maxX = proj.X;
if (proj.Y < minY) minY = proj.Y;
else if (proj.Y > maxY) maxY = proj.Y;
if (proj.Z < minZ) minZ = proj.Z;
else if (proj.Z > maxZ) maxZ = proj.Z;
}
// построение нового Extents3d по габаритам спроецированных точек (заведомо больше чем заданные!)
Extents3d projExt = new Extents3d(new Point3d(minX, minY, minZ), new Point3d(maxX, maxY, maxZ));
return picked.IsInside(projExt);
}
/// <summary>
/// Gets a value indicating whether the specified point is inside the extents.
/// </summary>
/// <param name="pt">The instance to which the method applies.</param>
/// <param name="extents">The extents 3d supposed to contain the point.</param>
/// <returns>true if the point is inside the extents; otherwise, false.</returns>
public static bool IsInside(this Point3d pt, Extents3d extents, double tolerance = 0.0000001)
{
return
(pt.X > extents.MinPoint.X - tolerance) &&
(pt.Y > extents.MinPoint.Y - tolerance) &&
(pt.Z > extents.MinPoint.Z - tolerance) &&
(pt.X < extents.MaxPoint.X + tolerance) &&
(pt.Y < extents.MaxPoint.Y + tolerance) &&
(pt.Z < extents.MaxPoint.Z + tolerance);
}