16Size::Size(
double width,
double height,
double depth) {
w=width;
h=height;
d=depth; }
47 return ( (
w != 0) || (
h != 0) || (
d != 0) );
97 (this->size == p.
size) );
102 (this->
x == (
int)p.
x) &&
103 (this->y == (
int)p.
y) &&
104 (this->z == (
int)p.
z) &&
105 (this->size == p.
size) );
165 np.
x = (int)(np.
x - a);
166 np.
y = (int)(np.
y - a);
167 np.
z = (int)(np.
z - a);
172 np.
x = (int)(np.
x + a);
173 np.
y = (int)(np.
y + a);
174 np.
z = (int)(np.
z + a);
179 np.
x = (int)(np.
x * a);
180 np.
y = (int)(np.
y * a);
181 np.
z = (int)(np.
z * a);
191bool Point::set(
int xx,
int yy,
int zz) {
x = xx;
y = yy;
z = zz;
return true; }
198 return sqrt( pow((
double)(
getX()-p.
getX()), 2) + pow((
double)(
getY()-p.
getY()), 2) );
201 return sqrt( pow((
double)(
getX()-p.
getX()), 2) + pow((
double)(
getY()-p.
getY()), 2) );
205 if (
size.isNonZero())
223 p.
setX((
int)this->
x);
224 p.
setY((
int)this->
y);
225 p.
setZ((
int)this->
z);
246 (this->size == p.
size) );
254 (this->size == p.
size) );
353 if (
size.isNonZero()) {
430 return (uint32)
lines.size();
434 if (pos >
lines.size())
439 lines.push_back(line);
443 lines[pos] = newline;
452 if (
lines.size() == 0)
453 return "PolyLine: (empty)";
454 std::string str =
"PolyLine: ";
456 for (n=0; n<=
lines.size()-1; n++) {
494Box::Box(
double x,
double y,
double w,
double h,
double linewidth) {
498 if (
size.getWidth() < 0) {
503 if (
size.getHeight() < 0) {
504 size.setHeight(-1*
size.getHeight());
516 if (
size.getWidth() < 0) {
521 if (
size.getHeight() < 0) {
522 size.setHeight(-1*
size.getHeight());
534 if (
size.getWidth() < 0) {
539 if (
size.getHeight() < 0) {
540 size.setHeight(-1*
size.getHeight());
610 return size.getWidth();
614 return size.getHeight();
695bool Box::set(
double x,
double y,
double w,
double h,
double linewidth) {
699 if (
size.getWidth() < 0) {
704 if (
size.getHeight() < 0) {
705 size.setHeight(-1*
size.getHeight());
743 if ( point.
getX() > this->getRightX() )
745 else if ( point.
getX() < this->getLeftX() )
747 else if ( point.
getY() < this->getUpperY() )
749 else if ( point.
getY() > this->getLowerY() )
759 return (!
size.isNonZero());
765 (this->upperLeft == otherbox.
upperLeft) &&
786 if ( ( dif =
upperLeft.x - (point.
x - padX) ) > 0 ) {
790 if ( ( dif =
upperLeft.y - (point.
y - padY) ) > 0 ) {
806 double left, right, top, bottom;
836 if ( otherbox.
getLeftX() > this->getRightX() )
838 else if ( otherbox.
getRightX() < this->getLeftX() )
840 else if ( otherbox.
getLowerY() < this->getUpperY() )
842 else if ( otherbox.
getUpperY() > this->getLowerY() )
847 double left, right, top, bottom;
878 double myArea =
size.getArea();
882 if ( (myArea > overlapArea) && (myArea != 0.0) )
883 return ( overlapArea / myArea );
884 else if (overlapArea != 0.0)
885 return ( myArea / overlapArea );
959 return (
x*v.
x) + (
y*v.
y);
1019 return set(p1.
x, p1.
y, p2.
x, p2.
y);
1023 return set(x2-x1, y2-y1);
1031 if (len == 0)
return false;
1043 return sqrt((
x*
x) + (
y*
y));
1047 return (
x*v.
y) - (
y*v.
x);
1051 return (*
this*v == 0);
1055 return (
det(v) == 0);
1060 return unit*(*
this*unit);
1070 if (len == 0)
return vect;
1071 double v = 1.0 / len;
1079 if ((
x == 0) && (
y == 0))
return vect;
1080 vect.
x =
x * cos(angle) -
y * sin(angle);
1081 vect.
y =
x * sin(angle) +
y * cos(angle);
1086 if ((
x == 0) && (
y == 0))
return false;
1087 double newX =
x * cos(angle) -
y * sin(angle);
1088 double newY =
x * sin(angle) +
y * cos(angle);
1102 return acos((*
this*v)/lengths);
1106 return fabs(
det(v));
1156 return (
x*v.
x) + (
y*v.
y) + (
z*v.
z);
1225 return set(p1.
x, p1.
y, p1.
z, p2.
x, p2.
y, p2.
z);
1228bool Vector3D::set(
double x1,
double y1,
double z1,
double x2,
double y2,
double z2) {
1229 return set(x2-x1, y2-y1, z2-z1);
1242 return sqrt((
x*
x) + (
y*
y) + (
z*
z));
1247 this->
y*v.
z - this->z*v.
y,
1248 this->z*v.
x - this->x*v.
z,
1249 this->x*v.
y - this->y*v.
x);
1253 return (*
this*v == 0);
1262 return unit*(*
this*unit);
1266 return *
this*(1.0/
length());
1273 return acos((*
this*v)/lengths);
1291 init(red, green, blue);
1295 init(color.
r, color.
g, color.
b);
1306bool Color::init(uint8 red, uint8 green, uint8 blue) {
1314bool Color::init(
const char* colorName) {
1316 if (!colorName || !strlen(colorName))
1317 return init(0, 0, 0);
1319 if (strchr(colorName,
',')) {
1323 else if (col.size() == 3)
1339 std::map<std::string, std::array<uint8, 3> >::const_iterator i =
ColorMap.find(colorName);
1341 return init((*i).second.at(0), (*i).second.at(1), (*i).second.at(2));
1343 return init(0, 0, 0);
1366 resColor.
r = (uint8)(color.
r*(1 - weight) + this->r*weight);
1367 resColor.
g = (uint8)(color.
g*(1 - weight) + this->g*weight);
1368 resColor.
b = (uint8)(color.
b*(1 - weight) + this->b*weight);
1373 return (uint8)(((double)
r +
g +
b) / 3.0);
1378 resColor.
r = 255 -
r;
1379 resColor.
g = 255 -
g;
1380 resColor.
b = 255 -
b;
1385 return pow((
double)pow((
double)
r - otherColor.
r, 2) + pow((
double)
g - otherColor.
g, 2) + pow((
double)
b - otherColor.
b, 2), (1.0 / 3));
1390 int rcount = (int)(count / 3);
1391 if (rcount <= 0) rcount = 1;
1392 int gcount = (int)(count / 3);
1393 if (gcount <= 0) gcount = 1;
1394 int bcount = count - rcount - gcount;
1395 if (bcount <= 0) bcount = 1;
1398 std::vector<Color> col;
1400 for (n = 0; n<rcount; n++) {
1401 value = (int)((n + 1)*(255.0 / rcount));
1402 if (value >= 256) value = 255;
1403 col.push_back(
Color(value, 0, 0));
1405 for (n = 0; n<gcount; n++) {
1406 value = (int)((n + 1)*(255.0 / gcount));
1407 if (value >= 256) value = 255;
1408 col.push_back(
Color(0, value, 0));
1410 for (n = 0; n<bcount; n++) {
1411 value = (int)((n + 1)*(255.0 / bcount));
1412 if (value >= 256) value = 255;
1413 col.push_back(
Color(0, 0, value));
1418 std::random_device rd;
1419 std::mt19937
g(rd());
1420 std::shuffle(col.begin(), col.end(),
g);
1434 srand((uint32)(uint64)
this);
1477 const double EPS = 1e-9;
1483 if (fabs(s.
getArea() - 12.0) > EPS) {
unittest::fail(
"MathClasses test: Size::getArea expected 12 got %.6f\n", s.
getArea());
return false; }
1488 if (zero.
isNonZero()) {
unittest::fail(
"MathClasses test: empty Size::isNonZero expected false\n");
return false; }
1490 if (!(s == s2)) {
unittest::fail(
"MathClasses test: Size::operator== expected equal\n");
return false; }
1493 if (fabs(scaled.
getWidth() - 6.0) > EPS || fabs(scaled.
getHeight() - 2.0) > EPS) {
1505 if (diff.
getX() != 3 || diff.
getY() != 4) {
unittest::fail(
"MathClasses test: Point::operator- expected (3,4) got (%d,%d)\n", diff.
getX(), diff.
getY());
return false; }
1507 if (sum.
getX() != 3 || sum.
getY() != 4) {
unittest::fail(
"MathClasses test: Point::operator+ expected (3,4)\n");
return false; }
1508 if (!(b ==
Point(3, 4))) {
unittest::fail(
"MathClasses test: Point::operator== expected equal\n");
return false; }
1515 if (fabs(v.
length() - 5.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::length expected 5 got %.6f\n", v.
length());
return false; }
1520 if (fabs(dot - 11.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D dot expected 11 got %.6f\n", dot);
return false; }
1523 if (fabs(a.det(b) - (-2.0)) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::det expected -2 got %.6f\n", a.det(b));
return false; }
1526 if (fabs(a.getArea(b) - 2.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::getArea expected 2 got %.6f\n", a.getArea(b));
return false; }
1529 Vector2D ex(1.0, 0.0), ey(0.0, 1.0);
1530 if (!ex.isOrthogonalWith(ey)) {
unittest::fail(
"MathClasses test: Vector2D::isOrthogonalWith expected true\n");
return false; }
1531 if (ex.isOrthogonalWith(ex)) {
unittest::fail(
"MathClasses test: Vector2D::isOrthogonalWith(self) expected false\n");
return false; }
1534 if (!
Vector2D(1.0, 1.0).isParallelWith(
Vector2D(2.0, 2.0))) {
unittest::fail(
"MathClasses test: Vector2D::isParallelWith expected true\n");
return false; }
1537 if (fabs(ex.getAngle(ey) - (M_PI / 2.0)) > 1e-6) {
unittest::fail(
"MathClasses test: Vector2D::getAngle expected pi/2 got %.6f\n", ex.getAngle(ey));
return false; }
1541 if (fabs(unit.
length() - 1.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::getUnitVector length expected 1 got %.6f\n", unit.
length());
return false; }
1542 if (fabs(unit.
x - 0.6) > EPS || fabs(unit.
y - 0.8) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::getUnitVector expected (0.6,0.8) got (%.3f,%.3f)\n", unit.
x, unit.
y);
return false; }
1546 if (fabs(ortho.
x - 0.0) > EPS || fabs(ortho.
y - 1.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::getOrthogonalVector expected (0,1) got (%.3f,%.3f)\n", ortho.
x, ortho.
y);
return false; }
1547 if (!ex.isOrthogonalWith(ortho)) {
unittest::fail(
"MathClasses test: orthogonal vector not orthogonal\n");
return false; }
1551 if (fabs(proj.
x - 2.0) > EPS || fabs(proj.
y - 0.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::getProjectionOn expected (2,0) got (%.3f,%.3f)\n", proj.
x, proj.
y);
return false; }
1555 if (fabs(rot.
x - 0.0) > 1e-9 || fabs(rot.
y - 1.0) > 1e-9) {
unittest::fail(
"MathClasses test: Vector2D::rotate(pi/2) expected (0,1) got (%.6f,%.6f)\n", rot.
x, rot.
y);
return false; }
1559 if (!sl.
setLength(10.0)) {
unittest::fail(
"MathClasses test: Vector2D::setLength returned false\n");
return false; }
1560 if (fabs(sl.
length() - 10.0) > 1e-6) {
unittest::fail(
"MathClasses test: Vector2D::setLength expected length 10 got %.6f\n", sl.
length());
return false; }
1563 if (fabs(mu.
length() - 1.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::makeUnitVector expected length 1 got %.6f\n", mu.
length());
return false; }
1568 if (fabs(c.
x - 3.0) > EPS || fabs(c.
y - 4.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::operator+= expected (3,4)\n");
return false; }
1570 if (fabs(c.
x - 6.0) > EPS || fabs(c.
y - 8.0) > EPS) {
unittest::fail(
"MathClasses test: Vector2D::operator*= expected (6,8)\n");
return false; }
1572 if (!(scaledV ==
Vector2D(4.0, 6.0))) {
unittest::fail(
"MathClasses test: Vector2D::operator*(double) expected (4,6)\n");
return false; }
1580 if (fabs(v.
length() - 7.0) > EPS) {
unittest::fail(
"MathClasses test: Vector3D::length expected 7 got %.6f\n", v.
length());
return false; }
1583 Vector3D a(1.0, 2.0, 3.0), b(4.0, 5.0, 6.0);
1585 if (fabs(dot - 32.0) > EPS) {
unittest::fail(
"MathClasses test: Vector3D dot expected 32 got %.6f\n", dot);
return false; }
1588 Vector3D ex(1.0, 0.0, 0.0), ey(0.0, 1.0, 0.0), ez(0.0, 0.0, 1.0);
1590 if (!(cross == ez)) {
unittest::fail(
"MathClasses test: Vector3D::product(x,y) expected z got (%.3f,%.3f,%.3f)\n", cross.
x, cross.
y, cross.
z);
return false; }
1593 if (!ex.isOrthogonalWith(ey)) {
unittest::fail(
"MathClasses test: Vector3D::isOrthogonalWith expected true\n");
return false; }
1594 if (ex.isOrthogonalWith(ex)) {
unittest::fail(
"MathClasses test: Vector3D::isOrthogonalWith(self) expected false\n");
return false; }
1597 if (!
Vector3D(1.0, 2.0, 3.0).isParallelWith(
Vector3D(2.0, 4.0, 6.0))) {
unittest::fail(
"MathClasses test: Vector3D::isParallelWith expected true\n");
return false; }
1600 if (fabs(ex.getAngle(ey) - (M_PI / 2.0)) > 1e-6) {
unittest::fail(
"MathClasses test: Vector3D::getAngle expected pi/2 got %.6f\n", ex.getAngle(ey));
return false; }
1604 if (fabs(unit.
length() - 1.0) > EPS) {
unittest::fail(
"MathClasses test: Vector3D::getUnitVector length expected 1 got %.6f\n", unit.
length());
return false; }
1607 if (fabs(ex.getArea(ey) - 1.0) > EPS) {
unittest::fail(
"MathClasses test: Vector3D::getArea expected 1 got %.6f\n", ex.getArea(ey));
return false; }
1611 if (fabs(proj.
x - 2.0) > EPS || fabs(proj.
y) > EPS || fabs(proj.
z) > EPS) {
unittest::fail(
"MathClasses test: Vector3D::getProjectionOn expected (2,0,0)\n");
return false; }
1617 Box box(0.0, 0.0, 10.0, 20.0);
1618 if (fabs(box.
getArea() - 200.0) > EPS) {
unittest::fail(
"MathClasses test: Box::getArea expected 200 got %.6f\n", box.
getArea());
return false; }
1623 if (fabs(cm.
getX() - 5.0) > EPS || fabs(cm.
getY() - 10.0) > EPS) {
unittest::fail(
"MathClasses test: Box::getCM expected (5,10) got (%.3f,%.3f)\n", cm.
getX(), cm.
getY());
return false; }
1630 Box neg(10.0, 10.0, -5.0, -5.0);
1632 if (fabs(neg.
getWidth() - 5.0) > EPS || fabs(neg.
getHeight() - 5.0) > EPS) {
unittest::fail(
"MathClasses test: Box negative-size dimensions wrong\n");
return false; }
1635 Box b1(0.0, 0.0, 10.0, 10.0);
1636 Box b2(5.0, 5.0, 10.0, 10.0);
1638 if (fabs(overlap.
getArea() - 25.0) > EPS) {
unittest::fail(
"MathClasses test: Box::getOverlapBox area expected 25 got %.6f\n", overlap.
getArea());
return false; }
1642 if (fabs(bb.
getLeftX()) > EPS || fabs(bb.
getUpperY()) > EPS) {
unittest::fail(
"MathClasses test: Box::getBoundingBox origin expected (0,0)\n");
return false; }
1643 if (fabs(bb.
getArea() - 225.0) > EPS) {
unittest::fail(
"MathClasses test: Box::getBoundingBox area expected 225 got %.6f\n", bb.
getArea());
return false; }
1647 if (fabs(pct - 0.25) > EPS) {
unittest::fail(
"MathClasses test: Box::percentOverlap expected 0.25 got %.6f\n", pct);
return false; }
1650 Box far(100.0, 100.0, 10.0, 10.0);
1656 Box mv(0.0, 0.0, 4.0, 4.0);
1666 const int N = 200000;
1670 for (
int i = 0; i < N; i++) {
1671 Vector2D a((
double)(i % 17), (
double)(i % 13));
1672 Vector2D b((
double)(i % 7) + 1.0, (
double)(i % 5) + 1.0);
1678 unittest::detail(
"Vector2D ops: N=%d, sink=%.3f, acc=(%.3f,%.3f)\n", N, sink, acc.
x, acc.
y);
1680 unittest::metric(
"vector2d_op_throughput", (
double)N / us * 1e6,
"ops/s",
true);
1689 "Geometry math: Size, Point, Vector2D, Vector3D, Box",
"math");
Geometry and 2D/3D math value classes: Color, Size, Point, PointFloat, Line, PolyLine,...
CMSDK time: µs-resolution 64-bit timestamps and the Time Mapping Constant (TMC).
Small, dependency-free unit test harness used by all CMSDK object tests.
Axis-aligned rectangle defined by an upper-left corner and a Size, with overlap/containment math.
bool setSize(const Size &boxsize)
Set the extent.
bool setUpperLeft(const PointFloat &point)
Set the corner.
bool growToIncludePoint(const Point &point, int padX=0, int padY=0)
Enlarge to include point plus padding.
Box getOverlapBox(const Box &otherbox) const
double getLineWidth() const
PointFloat getLowerLeft() const
bool move(double dx, double dy)
Translate in place.
bool moveTo(double x, double y)
Move the upper-left corner to (x,y).
double percentOverlap(const Box &otherbox) const
Overlap between the two boxes as a fraction of the larger area.
bool isPointWithin(const PointFloat &point) const
PointFloat getCentreMass() const
Box operator-(const Point &p) const
Box translated by -p.
double lineWidth
Stroke width (drawing hint).
bool setLineWidth(double width)
Set the stroke width.
bool grow(double dw, double dh)
Enlarge by (dw,dh), keeping the upper-left corner.
bool growToBoundingBox(const Box &otherbox)
Enlarge in place to include otherbox.
PointFloat getUpperLeft() const
Box getDoubleSizeSameCenter()
double orientation
Optional rotation metadata (radians); not applied by the geometric queries.
Box operator+(const Point &p) const
Box translated by +p.
Box getConstrainedCopy(const Box &box)
std::string print()
Human-readable representation for debugging.
PointFloat upperLeft
Upper-left corner.
bool equals(const Box &otherbox) const
Exact geometric equality.
PointFloat getLowerRight() const
bool constrainTo(const Box &box)
Clip this box in place to lie within box.
Box getBoundingBox(const Box &otherbox) const
bool set(double x, double y, double w, double h, double linewidth=0)
Reset all geometry.
PointFloat getUpperRight() const
Box()
Empty box at the origin.
Color mixOn(Color &color, double weight)
Blend this color onto a background color.
static std::vector< Color > createColorsMaxDifference(uint32 count, bool mix=false)
Generate count colors spread for maximum mutual visual difference (e.g.
Color getReverseColor()
Component-wise inverse (255-r, 255-g, 255-b).
uint8 getGreyValue()
Grey value as the plain average (r+g+b)/3.
double distance(Color &otherColor)
Euclidean distance to another color in RGB space.
Line segment between two PointFloat endpoints with a drawing width.
double lineWidth
Stroke width (drawing hint).
Line()
Degenerate line at the origin.
PointFloat getStartPoint() const
double getLineWidth() const
std::string print()
Human-readable representation for debugging.
bool setLineWidth(double width)
Set the stroke width.
bool setStartPoint(PointFloat point)
Set the start point.
bool setEndPoint(PointFloat point)
Set the end point.
PointFloat getEndPoint() const
PointFloat startPoint
First endpoint.
PointFloat endPoint
Second endpoint.
Floating-point 3D point with an optional attached Size; float counterpart of Point.
PointFloat()
Origin (0,0,0).
bool setX(double v)
Set x.
std::string print()
Human-readable representation for debugging.
double getDistanceTo(const Point &p) const
Euclidean distance to an integer point.
double operator[](int n) const
Component access: 0=x, 1=y, 2=z.
bool setSize(Size s)
Set the attached size.
PointFloat operator+(const Point &p) const
Element-wise sum.
bool set(double x, double y, double z=0)
Set all coordinates.
bool setY(double v)
Set y.
bool operator==(const Point &p) const
Equality against an integer point.
bool setZ(double v)
Set z.
PointFloat operator*(const Point &p) const
Element-wise product.
PointFloat operator-(const Point &p) const
Element-wise difference.
Integer 3D point with an optional attached Size; interoperates with PointFloat and vectors.
Point operator*(const Point &p) const
Element-wise product.
int operator[](int n) const
Component access: 0=x, 1=y, 2=z.
bool setSize(Size s)
Set the attached size.
Point operator-(const Point &p) const
Element-wise difference.
double getDistanceTo(Point &p) const
Euclidean distance to another point.
std::string print()
Human-readable representation for debugging.
bool operator==(const Point &p) const
Exact coordinate equality.
bool set(int x, int y, int z=0)
Set all coordinates.
Point operator+(const Point &p) const
Element-wise sum.
uint32 getLineCount() const
std::string print()
Human-readable representation for debugging.
bool replaceLine(uint32 pos, Line newline)
Replace the segment at pos.
bool addLine(Line line)
Append a segment.
bool removeLine(uint32 pos)
Remove the segment at pos.
std::vector< Line > lines
The segments, in order.
Line getLine(uint32 pos) const
uint64 lastPointTime
Timestamp of the last generated point (ms).
bool setDirection(double dx, double dy)
Set the base movement direction per step.
Vector2D direction
Current movement direction.
Vector2D variation
Random variation applied per step.
bool setStartPoint(double x, double y)
Set the initial position.
bool setVariation(double var)
Set the random perturbation magnitude.
PointFloat generateNextPoint()
Advance one step and return the new position.
PointFloat lastPoint
Most recently generated position.
2D/3D extent (width, height, optional depth) stored as doubles.
bool setDepth(double depth)
Set depth.
bool equals(const Size &size) const
Exact component equality.
bool setHeight(double height)
Set height.
double d
Depth (0 for 2D use).
bool operator==(const Size &p) const
Same as equals().
double getDiagonalLenth() const
bool setWidth(double width)
Set width.
Size operator*(const Vector2D &v) const
Scale w by v.x and h by v.y.
std::string print()
Human-readable representation for debugging.
static UnitTestRunner & instance()
Access the singleton (created on first use).
void registerTest(const char *name, UnitTestFunc func, const char *description="", const char *category="", bool inDefaultRun=true)
Register a test with the runner.
2D vector with the usual linear algebra: dot product, determinant, projection, rotation,...
Vector2D getProjectionOn(const Vector2D &v) const
bool setLength(double l)
Rescale to length l, keeping direction.
Vector2D rotate(double angle)
Rotated copy; this vector is unchanged.
const Vector2D & operator-=(const Vector2D &v)
In-place subtract.
Vector2D getUnitVector() const
bool isParallelWith(const Vector2D &v) const
double operator*(const Vector2D &v) const
Dot product.
bool setX(double v)
Set x.
const Vector2D & operator*=(double a)
In-place scale.
double operator[](int n) const
Component access: 0=x, 1=y.
Vector2D getOrthogonalVector() const
Vector2D operator-(const Vector2D &v) const
Difference.
double getAngle(const Vector2D &v) const
Unsigned angle to v via acos of the normalized dot product.
bool set(const PointFloat &p1, const PointFloat &p2)
Set as p2-p1.
std::string print()
Human-readable representation for debugging.
Vector2D operator+(const Vector2D &v) const
Sum.
bool isOrthogonalWith(const Vector2D &v) const
const Vector2D & operator+=(const Vector2D &v)
In-place add.
bool makeUnitVector()
Normalize in place.
bool operator==(const Vector2D &v) const
Component equality.
bool setY(double v)
Set y.
bool rotateIt(double angle)
Rotate in place by angle radians (same convention as rotate()).
double det(const Vector2D &v) const
2D cross product / determinant (x*v.y - y*v.x); sign gives turn direction.
double getArea(const Vector2D &v) const
3D vector with dot/cross products, projection and angle math.
double getAngle(const Vector3D &v) const
bool operator==(const Vector3D &v) const
Component equality.
bool setZ(double v)
Set z.
Vector3D getProjectionOn(const Vector3D &v) const
bool setY(double v)
Set y.
bool isParallelWith(const Vector3D &v) const
double getArea(const Vector3D &v) const
bool setX(double v)
Set x.
std::string print()
Human-readable representation for debugging.
double operator[](int n) const
Component access: 0=x, 1=y, 2=z.
bool set(const PointFloat &p1, const PointFloat &p2)
Set as p2-p1.
Vector3D getUnitVector() const
bool isOrthogonalWith(const Vector3D &v) const
Vector3D product(const Vector3D &v) const
Cross product with v.
double operator*(const Vector3D &v) const
Dot product.
const Vector3D & operator+=(const Vector3D &v)
In-place add.
Vector3D operator+(const Vector3D &v) const
Sum.
const Vector3D & operator*=(double a)
In-place scale.
const Vector3D & operator-=(const Vector3D &v)
In-place subtract.
Vector3D operator-(const Vector3D &v) const
Difference.
uint64 GetTimeNow()
Return the current absolute time (µs since year 0) according to the TMC.
int64 GetTimeAge(uint64 t)
Age of a timestamp relative to now.
uint32 Ascii2Uint32(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 32-bit decimal integer from a substring.
std::vector< std::string > TextListSplit(const char *text, const char *split, bool keepEmpty=true, bool autoTrim=false)
Split text on a separator.
double RandomValue()
Uniform random double in [0,1).
std::string StringFormat(const char *format,...)
printf into a std::string.
void fail(const char *fmt,...)
Set an explanatory reason shown on the FAIL line.
void metric(const char *name, double value, const char *unit="", bool higherIsBetter=true)
Record a performance metric.
void detail(const char *fmt,...)
Verbose-only indented diagnostic line (shown only when verbose=1).
void progress(int percent, const char *action)
Report progress with a short description of the current action.
const std::map< std::string, std::array< uint8, 3 > > ColorMap
Lookup table mapping ~200 CSS/X11 color names (with and without spaces) to 8-bit RGB triplets; used b...
bool MathClasses_UnitTest()
Unit test for the MathClasses module (geometry / vectors / boxes).
void Register_MathClasses_Tests()