using System;
namespace MikeSheInOpenDA.Spatial
{
public class SpatialDefine : ISpatialDefine
{
///
/// _pt1 is the default point (for Type Point)
/// To define a 2D Rectangle or 3D Cuboid use two points on opposite
/// end of the rectangle or cube.
///
private IXYLayerPoint _pt1;
private IXYLayerPoint _pt2;
private GeometryTypes _geometry;
///
/// Default Constructor
///
public SpatialDefine()
{
_pt1 = new XYLayerPoint(-9999, -9999, -9999);
_pt2 = new XYLayerPoint(-9999, -9999, -9999);
_geometry = GeometryTypes.GeometryPoint;
}
///
/// Constructor 1D
///
public SpatialDefine(IXYLayerPoint pt1)
{
_pt1 = pt1;
_geometry = GeometryTypes.GeometryPoint;
}
///
/// Constructor 2D or 3D
///
public SpatialDefine(IXYLayerPoint pt1, IXYLayerPoint pt2, GeometryTypes gm)
{
_pt1 = pt1;
_pt2 = pt2;
_geometry = gm;
if (pt1.Layer != pt2.Layer)
{
throw new Exception("Layer number must be the same for the two points");
}
}
///
/// Get Geometry type of this class. Can be either 1D (point), 2D, 3D
///
public GeometryTypes Geometry
{
get
{
return _geometry;
}
}
///
/// Get the minimum X coordinate between the two points.
/// If it's a Geometry type Point, return pt1 x coordinate.
///
public double XMinCoordinate
{
get
{
if (_geometry == GeometryTypes.GeometryPoint)
{
return _pt1.X;
}
else
{
return _pt1.X < _pt2.X ? _pt1.X : _pt2.X ;
}
}
}
///
/// Get the minimum Y coordinate between the two points.
/// If it's a Geometry type Point, return pt1 y coordinate.
///
public double YMinCoordinate
{
get
{
if (_geometry == GeometryTypes.GeometryPoint)
{
return _pt1.Y;
}
else
{
return _pt1.Y < _pt2.Y ? _pt1.Y : _pt2.Y;
}
}
}
///
/// Get the maximum X coordinate between the two points.
/// If it's a Geometry type Point, return pt1 x coordinate.
///
public double XMaxCoordinate
{
get
{
if (_geometry == GeometryTypes.GeometryPoint)
{
return _pt1.X;
}
else
{
return _pt1.X > _pt2.X ? _pt1.X : _pt2.X;
}
}
}
///
/// Get the maximum Y coordinate between the two points.
/// If it's a Geometry type Point, return pt1 y coordinate.
///
public double YMaxCoordinate
{
get
{
if (_geometry == GeometryTypes.GeometryPoint)
{
return _pt1.Y;
}
else
{
return _pt1.Y > _pt2.Y ? _pt1.Y : _pt2.Y;
}
}
}
///
/// Get the Layer number.
/// Note that the layer numbers must be the same for the two points.
///
public int Layer
{
get
{
return _pt1.Layer;
}
}
///
/// Returns the spatial Midpoint of the entity
///
public IXYLayerPoint MidPoint
{
get {
if (_geometry == GeometryTypes.GeometryPoint)
{
return new XYLayerPoint(_pt1.X, _pt1.Y, _pt1.Layer);
}
else
{
return new XYLayerPoint((_pt1.X + _pt2.X) / 2, (_pt1.Y + _pt2.Y) / 2, _pt1.Layer);
}
}
}
///
/// Return whether the point is inside this structure.
/// If this structure is a 1D point, then the (x,y,layer) values must be the same.
///
/// The point to check wether it's within this object spatially.
/// layer specific
///
public bool PointInObject(IXYLayerPoint pt, bool layerIndifferent = false)
{
if (!layerIndifferent)
{
if (_geometry == GeometryTypes.GeometryPoint)
{
double EPSILON = 0.001;
if (Math.Abs(pt.X - _pt1.X) < EPSILON && Math.Abs(pt.Y - _pt1.Y) < EPSILON && pt.Layer == _pt1.Layer)
{ return true; }
else
{ return false; }
}
else // 2D or 3D case
if (pt.X > XMinCoordinate && pt.X < XMaxCoordinate &&
pt.Y > YMinCoordinate && pt.Y < YMaxCoordinate &&
pt.Layer == _pt1.Layer)
{
return true;
}
else
{
return false;
}
}
else
{
if (_geometry == GeometryTypes.GeometryPoint)
{
double EPSILON = 0.001;
if (Math.Abs(pt.X - _pt1.X) < EPSILON && Math.Abs(pt.Y - _pt1.Y) < EPSILON)
{ return true; }
else
{ return false; }
}
else // 2D or 3D case
if (pt.X > XMinCoordinate && pt.X < XMaxCoordinate &&
pt.Y > YMinCoordinate && pt.Y < YMaxCoordinate)
{
return true;
}
else
{
return false;
}
}
}
}
}