1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-14 14:24:10 +02:00

Generic geometry

This commit is contained in:
Brian Fiete 2023-07-27 07:17:14 -07:00
parent 559ac2f39e
commit 98e498bdf5
2 changed files with 79 additions and 54 deletions

View file

@ -4,18 +4,23 @@ using System.Text;
namespace Beefy.geom namespace Beefy.geom
{ {
public struct Point public struct Point<T>
where T : operator T + T, operator T - T, operator T * T, operator -T, IIsNaN, operator implicit int
where int : operator T <=> T
{ {
public float x; public T x;
public float y; public T y;
public this(float x, float y) public this(T x, T y)
{ {
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
public static Point operator-(Self lhs, Self rhs) => .(lhs.x - rhs.x, lhs.y - rhs.y); public static Self operator-(Self lhs, Self rhs) => .(lhs.x - rhs.x, lhs.y - rhs.y);
public static Point operator+(Self lhs, Self rhs) => .(lhs.x + rhs.x, lhs.y + rhs.y); public static Self operator+(Self lhs, Self rhs) => .(lhs.x + rhs.x, lhs.y + rhs.y);
} }
typealias Point = Point<float>;
typealias PointD = Point<double>;
} }

View file

@ -5,14 +5,16 @@ using Beefy.gfx;
namespace Beefy.geom namespace Beefy.geom
{ {
public struct Rect public struct Rect<T>
where T : operator T + T, operator T - T, operator T * T, operator -T, operator T / int, IIsNaN, operator implicit int
where int : operator T <=> T
{ {
public float mX; public T mX;
public float mY; public T mY;
public float mWidth; public T mWidth;
public float mHeight; public T mHeight;
public float Left public T Left
{ {
get get
{ {
@ -26,7 +28,7 @@ namespace Beefy.geom
} }
} }
public float Top public T Top
{ {
get get
{ {
@ -40,7 +42,7 @@ namespace Beefy.geom
} }
} }
public float Right public T Right
{ {
get get
{ {
@ -53,7 +55,7 @@ namespace Beefy.geom
} }
} }
public float Bottom public T Bottom
{ {
get get
{ {
@ -66,7 +68,7 @@ namespace Beefy.geom
} }
} }
public float Width public T Width
{ {
get get
{ {
@ -79,7 +81,7 @@ namespace Beefy.geom
} }
} }
public float Height public T Height
{ {
get get
{ {
@ -92,7 +94,10 @@ namespace Beefy.geom
} }
} }
public this(float x = 0, float y = 0, float width = 0, float height = 0) public T CenterX => mX + mWidth / 2;
public T CenterY => mY + mHeight / 2;
public this(T x = default, T y = default, T width = default, T height = default)
{ {
mX = x; mX = x;
mY = y; mY = y;
@ -100,7 +105,7 @@ namespace Beefy.geom
mHeight = height; mHeight = height;
} }
public void Set(float x = 0, float y = 0, float width = 0, float height = 0) mut public void Set(T x = 0, T y = 0, T width = 0, T height = 0) mut
{ {
mX = x; mX = x;
mY = y; mY = y;
@ -108,7 +113,7 @@ namespace Beefy.geom
mHeight = height; mHeight = height;
} }
public bool Intersects(Rect rect) public bool Intersects(Self rect)
{ {
return !((rect.mX + rect.mWidth <= mX) || return !((rect.mX + rect.mWidth <= mX) ||
(rect.mY + rect.mHeight <= mY) || (rect.mY + rect.mHeight <= mY) ||
@ -116,12 +121,12 @@ namespace Beefy.geom
(rect.mY >= mY + mHeight)); (rect.mY >= mY + mHeight));
} }
public void SetIntersectionOf(Rect rect1, Rect rect2) mut public void SetIntersectionOf(Self rect1, Self rect2) mut
{ {
float x1 = Math.Max(rect1.mX, rect2.mX); T x1 = Math.Max(rect1.mX, rect2.mX);
float x2 = Math.Min(rect1.mX + rect1.mWidth, rect2.mX + rect2.mWidth); T x2 = Math.Min(rect1.mX + rect1.mWidth, rect2.mX + rect2.mWidth);
float y1 = Math.Max(rect1.mY, rect2.mY); T y1 = Math.Max(rect1.mY, rect2.mY);
float y2 = Math.Min(rect1.mY + rect1.mHeight, rect2.mY + rect2.mHeight); T y2 = Math.Min(rect1.mY + rect1.mHeight, rect2.mY + rect2.mHeight);
if (((x2 - x1) < 0) || ((y2 - y1) < 0)) if (((x2 - x1) < 0) || ((y2 - y1) < 0))
{ {
mX = 0; mX = 0;
@ -138,13 +143,13 @@ namespace Beefy.geom
} }
} }
public void SetIntersectionOf(Rect rect1, float x, float y, float width, float height) mut public void SetIntersectionOf(Self rect1, T x, T y, T width, T height) mut
{ {
float x1 = Math.Max(rect1.mX, x); T x1 = Math.Max(rect1.mX, x);
float x2 = Math.Min(rect1.mX + rect1.mWidth, x + width); T x2 = Math.Min(rect1.mX + rect1.mWidth, x + width);
float y1 = Math.Max(rect1.mY, y); T y1 = Math.Max(rect1.mY, y);
float y2 = Math.Min(rect1.mY + rect1.mHeight, y + height); T y2 = Math.Min(rect1.mY + rect1.mHeight, y + height);
if (((x2 - x1) < 0) || ((y2 - y1) < 0)) if (((x2 - x1) < default) || ((y2 - y1) < default))
{ {
mX = 0; mX = 0;
mY = 0; mY = 0;
@ -160,58 +165,70 @@ namespace Beefy.geom
} }
} }
public Rect Intersection(Rect rect) public Self Intersection(Self rect)
{ {
float x1 = Math.Max(mX, rect.mX); T x1 = Math.Max(mX, rect.mX);
float x2 = Math.Min(mX + mWidth, rect.mX + rect.mWidth); T x2 = Math.Min(mX + mWidth, rect.mX + rect.mWidth);
float y1 = Math.Max(mY, rect.mY); T y1 = Math.Max(mY, rect.mY);
float y2 = Math.Min(mY + mHeight, rect.mY + rect.mHeight); T y2 = Math.Min(mY + mHeight, rect.mY + rect.mHeight);
if (((x2 - x1) < 0) || ((y2 - y1) < 0)) if (((x2 - x1) < default) || ((y2 - y1) < default))
return Rect(0, 0, 0, 0); return default;
else else
return Rect(x1, y1, x2 - x1, y2 - y1); return Self(x1, y1, x2 - x1, y2 - y1);
} }
public Rect Union(Rect rect) public Self Union(Self rect)
{ {
float x1 = Math.Min(mX, rect.mX); T x1 = Math.Min(mX, rect.mX);
float x2 = Math.Max(mX + mWidth, rect.mX + rect.mWidth); T x2 = Math.Max(mX + mWidth, rect.mX + rect.mWidth);
float y1 = Math.Min(mY, rect.mY); T y1 = Math.Min(mY, rect.mY);
float y2 = Math.Max(mY + mHeight, rect.mY + rect.mHeight); T y2 = Math.Max(mY + mHeight, rect.mY + rect.mHeight);
return Rect(x1, y1, x2 - x1, y2 - y1); return Self(x1, y1, x2 - x1, y2 - y1);
} }
public bool Contains(float x, float y) public void Include(Point<T> pt) mut
{
T left = mX;
T top = mY;
T right = mX + mWidth;
T bottom = mY + mHeight;
mX = Math.Min(pt.x, left);
mY = Math.Min(pt.y, top);
mWidth = Math.Max(pt.x, right) - mX;
mHeight = Math.Max(pt.y, bottom) - mY;
}
public bool Contains(T x, T y)
{ {
return ((x >= mX) && (x < mX + mWidth) && return ((x >= mX) && (x < mX + mWidth) &&
(y >= mY) && (y < mY + mHeight)); (y >= mY) && (y < mY + mHeight));
} }
public bool Contains(Point pt) public bool Contains(Point<T> pt)
{ {
return Contains(pt.x, pt.y); return Contains(pt.x, pt.y);
} }
public bool Contains(Rect rect) public bool Contains(Self rect)
{ {
return Contains(rect.mX, rect.mY) && Contains(rect.mX + rect.mWidth, rect.mY + rect.mHeight); return Contains(rect.mX, rect.mY) && Contains(rect.mX + rect.mWidth, rect.mY + rect.mHeight);
} }
public void Offset(float x, float y) mut public void Offset(T x, T y) mut
{ {
mX += x; mX += x;
mY += y; mY += y;
} }
public void Inflate(float x, float y) mut public void Inflate(T x, T y) mut
{ {
mX -= x; mX -= x;
mWidth += x * 2; mWidth += x + x;
mY -= y; mY -= y;
mHeight += y * 2; mHeight += y + y;
} }
public void Scale(float scaleX, float scaleY) mut public void Scale(T scaleX, T scaleY) mut
{ {
mX *= scaleX; mX *= scaleX;
mY *= scaleY; mY *= scaleY;
@ -219,11 +236,14 @@ namespace Beefy.geom
mHeight *= scaleY; mHeight *= scaleY;
} }
public void ScaleFrom(float scaleX, float scaleY, float centerX, float centerY) mut public void ScaleFrom(T scaleX, T scaleY, T centerX, T centerY) mut
{ {
Offset(-centerX, -centerY); Offset(-centerX, -centerY);
Scale(scaleX, scaleY); Scale(scaleX, scaleY);
Offset(centerX, centerY); Offset(centerX, centerY);
} }
} }
typealias Rect = Rect<float>;
typealias RectD = Rect<double>;
} }