System.Types.TPointF
Delphi
TPointF = record
class function Create(const AX, AY: Single): TPointF; overload; static; inline;
class function Create(const APoint: TPoint): TPointF; overload; static; inline;
class operator Add(const APoint1, APoint2: TPointF): TPointF;
class operator Subtract(const APoint1, APoint2: TPointF): TPointF;
class operator Equal(const APoint1, APoint2: TPointF): Boolean;
class operator NotEqual(const APoint1, APoint2: TPointF): Boolean;
class operator Implicit(const APoint: TPoint): TPointF;
class operator Negative(const APoint: TPointF): TPointF;
class operator Multiply(const APoint1, APoint2: TPointF): TPointF;
class operator Multiply(const APoint: TPointF; const AFactor: Single): TPointF;
class operator Multiply(const AFactor: Single; const APoint: TPointF): TPointF;
class operator Divide(const APoint: TPointF; const AFactor: Single): TPointF;
class function PointInCircle(const Point, Center: TPointF; const Radius: Integer): Boolean; static; inline;
class function Zero: TPointF; inline; static;
function Distance(const APoint: TPointF): Single;
function CrossProduct(const APoint: TPointF): Single;
function DotProduct(const APoint: TPointF): Single; inline;
procedure Offset(const APoint: TPointF); overload; inline;
procedure Offset(const ADeltaX, ADeltaY: Single); overload; inline;
procedure Offset(const APoint: TPoint); overload; inline;
procedure SetLocation(const X, Y: Single); overload; deprecated 'Use ":=" assignment instead';
procedure SetLocation(const P: TPointF); overload; deprecated 'Use ":=" assignment instead';
procedure SetLocation(const P: TPoint); overload; deprecated 'Use ":=" assignment instead';
function Subtract(const Point: TPointF): TPointF; overload; deprecated 'Use TPointF.Offset instead';
function Subtract(const Point: TPoint): TPointF; overload; deprecated 'Use TPointF.Offset instead';
function Add(const Point: TPointF): TPointF; overload; deprecated 'Use TPointF.Offset instead';
function Add(const Point: TPoint): TPointF; overload; deprecated 'Use TPointF.Offset instead';
function Scale(const AFactor: Single): TPointF; deprecated;
function EqualsTo(const Point: TPointF; const Epsilon: Single = 0): Boolean;
function IsZero: Boolean;
function Ceiling: TPoint;
function Truncate: TPoint;
function Round: TPoint;
function SnapToPixel(const AScale: Single; const APlaceBetweenPixels: Boolean = True): TPointF;
function Normalize: TPointF;
function Length: Single;
function Rotate(const AAngle: Single): TPointF;
function Reflect(const APoint: TPointF): TPointF; inline;
function MidPoint(const APoint: TPointF): TPointF; inline;
function AngleCosine(const APoint: TPointF): Single;
function Angle(const APoint: TPointF): Single;
case Integer of
0: (V: TPointFType;);
1: (X: Single;
Y: Single;);
end;
C++
struct TPointF : public POINTF
{
#else
struct TPointF
{
float x;
float y;
#endif
TPointF() _ALWAYS_INLINE
{ x = y = 0; }
TPointF(float _x, float _y) _ALWAYS_INLINE
{ x=_x; y=_y; }
TPointF(const POINT& pt) _ALWAYS_INLINE {
x = pt.x;
y = pt.y;
}
bool operator ==(const TPointF& pt) const {
return _sameValue(x, pt.x) && _sameValue(y, pt.y);
}
bool operator !=(const TPointF& pt) const {
return !(pt == *this);
}
TPointF operator +(const TPointF& rhs) const {
return TPointF(rhs.x + this->x, rhs.y + this->y);
}
TPointF operator -(const TPointF& rhs) const {
return TPointF(this->x - rhs.x, this->y - rhs.y);
}
TPointF operator-() const { return TPointF(-this->x, -this->y); }
TPointF operator *(float f) const {
return TPointF(this->x * f, this->y * f);
}
TPointF operator *(const TPointF &P) const {
return TPointF(this->x * P.x, this->y * P.y);
}
friend TPointF operator*(float, const TPointF &);
TPointF operator /(float f) const {
return TPointF(this->x / f, this->y / f);
}
TPointF& operator +=(const TPointF& rhs) {
this->x += rhs.x;
this->y += rhs.y;
return *this;
}
TPointF& operator -=(const TPointF& rhs) {
this->x -= rhs.x;
this->y -= rhs.y;
return *this;
}
TPointF& operator *=(float f) {
this->x *= f;
this->y *= f;
return *this;
}
TPointF& operator *=(const TPointF &P) {
this->x *= P.x;
this->y *= P.y;
return *this;
}
TPointF& operator /=(float f) {
this->x /= f;
this->y /= f;
return *this;
}
bool IsZero() const _ALWAYS_INLINE {
return _sameValue(x, 0.0F) && _sameValue(y, 0.0F);
}
bool IsEmpty() const _ALWAYS_INLINE {
return IsZero();
}
void Offset(float DX, float DY) _ALWAYS_INLINE {
x += DX;
y += DY;
}
void SetLocation(float nX, float nY) _ALWAYS_INLINE {
x = nX;
y = nY;
}
void SetLocation(const TPointF& p) _ALWAYS_INLINE {
x = p.x;
y = p.y;
}
double Distance(const TPointF& p2) const _ALWAYS_INLINE {
#ifdef _WIN64 // RS-53817
return System::hypotWA(p2.x - this->x, p2.y - this->y);
#else
return hypot(p2.x - this->x, p2.y - this->y);
#endif
}
TPoint Ceiling() const _ALWAYS_INLINE {
return TPoint((int32_t)ceil(this->x), (int32_t)ceil(this->y));
}
TPoint Truncate() const _ALWAYS_INLINE {
return TPoint((int32_t)floor(this->x), (int32_t)floor(this->y));
}
TPoint Round() const _ALWAYS_INLINE {
return TPoint((int32_t)floor(this->x + 0.5), (int32_t)floor(this->y + 0.5));
}
bool PtInCircle(const TPointF& CircleCenter, float Radius) const _ALWAYS_INLINE {
return (Radius > 0.0F) && ((_sqrf(CircleCenter.x-x)+_sqrf(CircleCenter.y-y)) < _sqrf(Radius));
}
float CrossProduct(const TPointF& rhs) const _ALWAYS_INLINE {
return x * rhs.y - y * rhs.x;
}
float DotProduct(const TPointF &rhs) const _ALWAYS_INLINE {
return (x*rhs.x)+(y*rhs.y);
}
TPointF SnapToPixel(float Scale,
bool PlaceBetweenPixels = true) const _ALWAYS_INLINE {
TPointF result;
if (Scale <= 0.0f) Scale = 1.0f;
result.x = _roundf(x * Scale) / Scale;
result.y = _roundf(y * Scale) / Scale;
if (PlaceBetweenPixels) {
Scale /= 2.0f;
result.Offset(Scale, Scale);
}
return result;
}
float Length() const _ALWAYS_INLINE { return hypot(x, y); }
TPointF Normalize() const _ALWAYS_INLINE {
TPointF result = *this;
float dist = Length();
if (dist != 0.0f) {
result.x /= dist;
result.y /= dist;
}
return result;
}
TPointF Rotate(float Angle) const _ALWAYS_INLINE {
float s = sin(Angle);
float c = cos(Angle);
return TPointF((x * c) - (y * s), (x * s) + (y * c));
}
TPointF Reflect(const TPointF& P) const _ALWAYS_INLINE {
return (*this) + P * (-2.0f * DotProduct(P));
}
TPointF MidPoint(const TPointF &P) const _ALWAYS_INLINE {
return TPointF( (x+P.x)/2.0f,(y+P.y)/2.0f);
}
float AngleCosine(const TPointF& P) const _ALWAYS_INLINE {
float result = Length() * P.Length();
if (result > FLT_EPSILON) {
result = DotProduct(P) / result;
} else {
result = DotProduct(P) / FLT_EPSILON;
}
return (result > 1.0f) ? 1.0f : ((result < -1.0f) ? -1.0f : result);
}
float Angle(const TPointF &P) const _ALWAYS_INLINE {
return atan2(y-P.y,x-P.x);
}
static float __fastcall _sqrf(float i) _ALWAYS_INLINE {
return i*i;
}
static bool __fastcall _sameValue(float a, float b) {
const float SINGLE_RESOLUTION = 1.25E-6f;
const float SINGLE_ZERO =6.25E-37f;
float _epsilon = (float) ((fabs(a) > fabs(b)) ? fabs(a): fabs(b)) * SINGLE_RESOLUTION;
if (_epsilon == 0)
_epsilon = SINGLE_ZERO; // both a and b are very little, _epsilon was 0 because of normalization
return (a > b) ? ((a - b) <= _epsilon): ((b - a) <= _epsilon);
}
__property float X = { read=x, write=x };
__property float Y = { read=y, write=y };
};
typedef TPointF tagPointF;
struct TRectF {
float left;
float top;
float right;
float bottom;
TRectF() _ALWAYS_INLINE
{ init(0,0,0,0); }
TRectF(const TPointF& TL) _ALWAYS_INLINE {
init(TL.x, TL.y, TL.x, TL.y);
}
TRectF(const TPointF& TL, float width, float height) _ALWAYS_INLINE {
init (TL.x, TL.y, TL.x + width, TL.y + height);
}
TRectF(float l, float t, float r, float b) _ALWAYS_INLINE {
init(l, t, r, b);
}
TRectF(const TPointF& TL, const TPointF& BR) _ALWAYS_INLINE {
init(TL.x, TL.y, BR.x, BR.y);
Normalize();
}
TRectF(const RECT& r) _ALWAYS_INLINE {
init(r.left, r.top, r.right, r.bottom);
}
void init(float l, float t, float r, float b) {
left = l; top = t;
right = r; bottom = b;
}
TPointF& TopLeft() _ALWAYS_INLINE
{ return *((TPointF* )this); }
TPointF& BottomRight() _ALWAYS_INLINE
{ return *((TPointF* )this+1); }
const TPointF& TopLeft() const _ALWAYS_INLINE
{ return *((TPointF* )this); }
const TPointF& BottomRight() const _ALWAYS_INLINE
{ return *((TPointF* )this+1); }
float Width() const _ALWAYS_INLINE
{ return right - left; }
float Height() const _ALWAYS_INLINE
{ return bottom - top ; }
static TRectF Empty() _ALWAYS_INLINE
{ return TRectF(); }
void Normalize() _ALWAYS_INLINE {
if (top > bottom) {
float temp = top;
top = bottom;
bottom = temp;
}
if (left > right) {
float temp = left;
left = right;
right = temp;
}
}
bool operator ==(const TRectF& rc) const
{
return _sameValue(left, rc.left) && _sameValue(top, rc.top) &&
_sameValue(right, rc.right) && _sameValue(bottom, rc.bottom);
}
bool operator !=(const TRectF& rc) const
{ return !(rc == *this); }
bool IsEmpty() const _ALWAYS_INLINE {
return _sameValue(right, left) || _sameValue(bottom, top); // differs from Delphi version
}
bool Contains(const TPointF& p) const _ALWAYS_INLINE {
return ((p.x > left || _sameValue(p.x, left)) && (p.y > top || _sameValue(p.y, top)) && (p.x < right) && (p.y < bottom));
}
bool PtInRect(const TPointF& p) const _ALWAYS_INLINE {
return Contains(p);
}
bool Contains(const TRectF& r) const _ALWAYS_INLINE {
return Contains(r.TopLeft()) && Contains(r.BottomRight());
}
bool Overlaps(const TRectF &r) const _ALWAYS_INLINE {
return IntersectsWith(r);
}
bool Intersects(const TRectF &r) const _ALWAYS_INLINE {
return IntersectsWith(r);
}
bool IntersectsWith(const TRectF &r) const _ALWAYS_INLINE {
return !( (BottomRight().x < r.TopLeft().x) ||
(BottomRight().y < r.TopLeft().y) ||
(r.BottomRight().x < TopLeft().x) ||
(r.BottomRight().y < TopLeft().y) );
}
static TRectF Intersect(const TRectF &r1, const TRectF &r2);
void Intersect(const TRectF &r);
void Union(const TRectF &r);
static TRectF Union(const TRectF &r1, const TRectF &r2);
static TRectF Union(const TPointF* points, int npoints) _ALWAYS_INLINE {
TPointF tl, br;
if (npoints > 0) {
tl.SetLocation(points[0]);
br.SetLocation(points[0]);
for (int i = npoints; --i > 0;) {
if (points[i].x < tl.x)
tl.x = points[i].x;
if (points[i].x > br.x)
br.x = points[i].x;
if (points[i].y < tl.y)
tl.y = points[i].y;
if (points[i].y > br.y)
br.y = points[i].y;
}
}
return TRectF(tl, br);
}
void Offset(float DX, float DY) _ALWAYS_INLINE {
left += DX;
right += DX;
top += DY;
bottom += DY;
}
void SetLocation(float X, float Y) _ALWAYS_INLINE {
Offset(X - left, Y - top);
}
void SetLocation(const TPointF& p) _ALWAYS_INLINE {
Offset(p.x - left, p.y - top);
}
void Inflate(float DX, float DY) _ALWAYS_INLINE {
left -= DX;
right += DX;
top -= DY;
bottom += DY;
}
void Inflate(float l, float t, float r, float b) _ALWAYS_INLINE {
left -= l;
right += r;
top -= t;
bottom += b;
}
void NormalizeRect() _ALWAYS_INLINE {
float temp;
if (left > right)
{
temp = left;
left = right;
right = temp;
}
if (top > bottom)
{
temp = top;
top = bottom;
bottom = temp;
}
}
TPointF CenterPoint() const _ALWAYS_INLINE {
return TPointF((left+right)/2.0F, (top+bottom)/2.0F);
}
TRect Ceiling() const _ALWAYS_INLINE {
return TRect(TopLeft().Ceiling(), BottomRight().Ceiling());
}
TRect Truncate() const _ALWAYS_INLINE {
return TRect(TopLeft().Truncate(), BottomRight().Truncate());
}
TRect Round() const _ALWAYS_INLINE {
return TRect(TopLeft().Round(), BottomRight().Round());
}
TRectF CenteredRect(const TRectF &CenteredRect) const _ALWAYS_INLINE {
float w = CenteredRect.Width();
float h = CenteredRect.Height();
float x = (right + left)/2.0F;
float y = (top + bottom)/2.0F;
return TRectF(x-w/2.0F, y-h/2.0F, x+w/2.0F, y+h/2.0F);
}
TRectF CenterAt(const TRectF& Bounds) const _ALWAYS_INLINE {
TRectF result = *this;
result.Offset(-result.left, -result.top);
result.Offset(_roundf((Bounds.Width() - result.Width()) / 2.0f),
_roundf((Bounds.Height() - result.Height()) / 2.0f));
result.Offset(Bounds.left, Bounds.top);
return result;
}
float GetWidth() const _ALWAYS_INLINE {
return right - left;
}
void SetWidth(float width) _ALWAYS_INLINE {
right = left + width;
}
float GetHeight() const _ALWAYS_INLINE {
return bottom - top;
}
void SetHeight(float height) _ALWAYS_INLINE {
bottom = top + height;
}
TSizeF GetSize() const _ALWAYS_INLINE {
return TSizeF(GetWidth(), GetHeight());
}
void SetSize(const TSizeF& newSize) _ALWAYS_INLINE {
SetWidth(newSize.cx);
SetHeight(newSize.cy);
}
TPointF GetLocation() const _ALWAYS_INLINE {
return TPointF(left, top);
}
static float __fastcall _sqrf(float i) _ALWAYS_INLINE {
return i*i;
}
static bool __fastcall _sameValue(float a, float b) _ALWAYS_INLINE {
const float SINGLE_RESOLUTION = 1.25E-6f;
const float SINGLE_ZERO =6.25E-37f;
float _epsilon = (float) ((fabs(a) > fabs(b)) ? fabs(a): fabs(b)) * SINGLE_RESOLUTION;
if (_epsilon == 0)
_epsilon = SINGLE_ZERO; // both a and b are very little, _epsilon was 0 because of normalization
return (a > b) ? ((a - b) <= _epsilon): ((b - a) <= _epsilon);
}
TRectF FitInto(const TRectF& DesignatedArea,
float& Ratio) const _ALWAYS_INLINE {
if (DesignatedArea.Width() <= 0 || DesignatedArea.Height() <= 0) {
Ratio = 1;
return *this;
}
float rw = Width() / DesignatedArea.Width();
float rh = Height() / DesignatedArea.Height();
if (rw > rh)
Ratio = rw;
else
Ratio = rh;
TRectF result(0, 0, Width() / Ratio, Height() / Ratio);
return result.CenteredRect(DesignatedArea);
}
TRectF FitInto(const TRectF &DesignatedArea) const _ALWAYS_INLINE {
float Ratio;
return FitInto(DesignatedArea,Ratio);
}
TRectF SnapToPixel(float Scale,
bool PlaceBetweenPixels = true) const _ALWAYS_INLINE {
if (Scale <= 0.0f)
Scale = 1.0f;
TRectF result;
result.left = _roundf(left * Scale) / Scale;
result.top = _roundf(top * Scale) / Scale;
result.SetWidth(_roundf( Width() * Scale) / Scale);
result.SetHeight(_roundf( Height() * Scale) / Scale);
if (PlaceBetweenPixels) {
Scale /= 2.0f;
result.Offset(Scale, Scale);
}
return result;
}
TRectF PlaceInto(const TRectF &DesignatedArea, THorzRectAlign HorzAlign, TVertRectAlign VertAlign) const;
__property float Left = { read=left, write=left };
__property float Top = { read=top, write=top };
__property float Right = { read=right, write=right };
__property float Bottom = { read=bottom, write=bottom };
__property TSizeF Size = { read=GetSize, write=SetSize };
__property TPointF Location = { read=GetLocation, write=SetLocation };
};
} /* namespace Types */
Properties
Type | Visibility | Source | Unit | Parent |
---|---|---|---|---|
record struct |
public | System.Types.pas SystemTypes.h |
System.Types | System.Types |
Description
Defines a pixel location on-screen.
The TPointF type defines the floating-point X and Y coordinates of a pixel location on-screen, with the origin in the upper-left corner. X and Y specify the horizontal and vertical coordinates of a point, respectively.
The type of X and Y is Single.
The TPointF type is primarily used for the coordinates of FireMonkey objects.
See Also
- System.Types.TPointF.X
- System.Types.TPointF.Y
- System.Types.PointF
- System.Types.TPoint
- Type conversion routines