@mathigon/euclid
Advanced tools
Comparing version 1.1.7 to 1.1.8
@@ -67,5 +67,7 @@ // src/angle.ts | ||
} | ||
/** Finds the perpendicular distance between this point and a line. */ | ||
distanceFromLine(l) { | ||
return Point.distance(this, l.project(this)); | ||
} | ||
/** Clamps this point to specific bounds. */ | ||
clamp(bounds, padding = 0) { | ||
@@ -99,2 +101,3 @@ const x = clamp(this.x, bounds.xMin + padding, bounds.xMax - padding); | ||
} | ||
// Snap to the x or y values of another point | ||
snap(p, tolerance = 5) { | ||
@@ -107,2 +110,3 @@ if (nearlyEquals(this.x, p.x, tolerance)) | ||
} | ||
/** Calculates the average of multiple points. */ | ||
static average(...points) { | ||
@@ -113,2 +117,3 @@ const x = total(points.map((p) => p.x)) / points.length; | ||
} | ||
/** Calculates the dot product of two points p1 and p2. */ | ||
static dot(p1, p2) { | ||
@@ -123,11 +128,15 @@ return p1.x * p2.x + p1.y * p2.y; | ||
} | ||
/** Returns the Euclidean distance between two points p1 and p2. */ | ||
static distance(p1, p2) { | ||
return Math.sqrt(square(p1.x - p2.x) + square(p1.y - p2.y)); | ||
} | ||
/** Returns the Manhattan distance between two points p1 and p2. */ | ||
static manhattan(p1, p2) { | ||
return Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y); | ||
} | ||
/** Interpolates two points p1 and p2 by a factor of t. */ | ||
static interpolate(p1, p2, t = 0.5) { | ||
return new Point(lerp(p1.x, p2.x, t), lerp(p1.y, p2.y, t)); | ||
} | ||
/** Interpolates a list of multiple points. */ | ||
static interpolateList(points, t = 0.5) { | ||
@@ -138,2 +147,3 @@ const n = points.length - 1; | ||
} | ||
/** Creates a point from polar coordinates. */ | ||
static fromPolar(angle, r = 1) { | ||
@@ -150,2 +160,3 @@ return new Point(r * Math.cos(angle), r * Math.sin(angle)); | ||
} | ||
/** Check if p1, p2 and p3 lie on a straight line. */ | ||
static colinear(p1, p2, p3, tolerance) { | ||
@@ -158,2 +169,4 @@ const dx1 = p1.x - p2.x; | ||
} | ||
// --------------------------------------------------------------------------- | ||
/** Transforms this point using a 2x3 matrix m. */ | ||
transform(m) { | ||
@@ -164,2 +177,3 @@ const x = m[0][0] * this.x + m[0][1] * this.y + m[0][2]; | ||
} | ||
/** Rotates this point by a given angle (in radians) around point `c`. */ | ||
rotate(angle, c = ORIGIN) { | ||
@@ -176,2 +190,3 @@ if (nearlyEquals(angle, 0)) | ||
} | ||
/** Reflects this point across a line l. */ | ||
reflect(l) { | ||
@@ -256,29 +271,39 @@ const v = l.p2.x - l.p1.x; | ||
} | ||
/* The distance between the two points defining this line. */ | ||
get length() { | ||
return Point.distance(this.p1, this.p2); | ||
} | ||
/* The squared distance between the two points defining this line. */ | ||
get lengthSquared() { | ||
return (this.p1.x - this.p2.x) ** 2 + (this.p1.y - this.p2.y) ** 2; | ||
} | ||
/** The midpoint of this line. */ | ||
get midpoint() { | ||
return Point.average(this.p1, this.p2); | ||
} | ||
/** The slope of this line. */ | ||
get slope() { | ||
return (this.p2.y - this.p1.y) / (this.p2.x - this.p1.x); | ||
} | ||
/** The y-axis intercept of this line. */ | ||
get intercept() { | ||
return this.p1.y - this.slope * this.p1.x; | ||
} | ||
/** The angle formed between this line and the x-axis. */ | ||
get angle() { | ||
return rad(this.p2, this.p1); | ||
} | ||
/** The point representing a unit vector along this line. */ | ||
get unitVector() { | ||
return this.p2.subtract(this.p1).unitVector; | ||
} | ||
/** The point representing the perpendicular vector of this line. */ | ||
get perpendicularVector() { | ||
return new Point(this.p2.y - this.p1.y, this.p1.x - this.p2.x).unitVector; | ||
} | ||
/** Finds the line parallel to this one, going through point p. */ | ||
parallel(p) { | ||
return new Line(p, p.add(this.p2).subtract(this.p1)); | ||
} | ||
/** Finds the line perpendicular to this one, going through point p. */ | ||
perpendicular(p) { | ||
@@ -290,5 +315,7 @@ const q = this.line.project(p); | ||
} | ||
/** The perpendicular bisector of this line. */ | ||
get perpendicularBisector() { | ||
return this.perpendicular(this.midpoint); | ||
} | ||
/** Squared distance between a point and a line. */ | ||
distanceSquared(p) { | ||
@@ -307,2 +334,4 @@ const proj = this.project(p); | ||
} | ||
// --------------------------------------------------------------------------- | ||
/** Signed distance along the line (opposite of .at()). */ | ||
offset(p) { | ||
@@ -313,5 +342,7 @@ const a = Point.difference(this.p2, this.p1); | ||
} | ||
/** Projects a point `p` onto this line. */ | ||
project(p) { | ||
return this.at(this.offset(p)); | ||
} | ||
/** Returns which side of this line a point p is on (or 0 on the line). */ | ||
side(p, tolerance) { | ||
@@ -323,11 +354,15 @@ const a = Point.difference(this.p2, this.p1); | ||
} | ||
/** Checks if a point p lies on this line. */ | ||
contains(p, tolerance) { | ||
return this.side(p, tolerance) === 0; | ||
} | ||
/** Gets the point at a specific offset along the line (opposite of .offset()). */ | ||
at(t) { | ||
return Point.interpolate(this.p1, this.p2, t); | ||
} | ||
// --------------------------------------------------------------------------- | ||
transform(m) { | ||
return new this.constructor(this.p1.transform(m), this.p2.transform(m)); | ||
} | ||
/** Rotates this line by a given angle (in radians), optionally around point `c`. */ | ||
rotate(a, c = ORIGIN) { | ||
@@ -403,2 +438,3 @@ if (nearlyEquals2(a, 0)) | ||
} | ||
/** Contracts (or expands) a line by a specific ratio. */ | ||
contract(x) { | ||
@@ -424,5 +460,7 @@ return new Segment(this.at(x), this.at(1 - x)); | ||
} | ||
/** The length of the circumference of this circle. */ | ||
get circumference() { | ||
return TWO_PI * this.r; | ||
} | ||
/** The area of this circle. */ | ||
get area() { | ||
@@ -446,2 +484,3 @@ return Math.PI * this.r ** 2; | ||
} | ||
// --------------------------------------------------------------------------- | ||
project(p) { | ||
@@ -461,2 +500,3 @@ const proj = p.subtract(this.c).unitVector.scale(this.r); | ||
} | ||
// --------------------------------------------------------------------------- | ||
transform(m) { | ||
@@ -527,2 +567,3 @@ const scale = Math.abs(m[0][0]) + Math.abs(m[1][1]); | ||
} | ||
// --------------------------------------------------------------------------- | ||
project(p) { | ||
@@ -546,2 +587,3 @@ const start = this.startAngle; | ||
} | ||
// --------------------------------------------------------------------------- | ||
transform(m) { | ||
@@ -554,2 +596,3 @@ return new this.constructor( | ||
} | ||
/** Rotates this arc by a given angle (in radians), optionally around point `c`. */ | ||
rotate(a, c = ORIGIN) { | ||
@@ -1183,2 +1226,6 @@ if (nearlyEquals4(a, 0)) | ||
} | ||
/** | ||
* The (signed) area of this polygon. The result is positive if the vertices | ||
* are ordered clockwise, and negative otherwise. | ||
*/ | ||
get signedArea() { | ||
@@ -1220,2 +1267,3 @@ const p = this.points; | ||
} | ||
/** The oriented version of this polygon (vertices in clockwise order). */ | ||
get oriented() { | ||
@@ -1227,2 +1275,3 @@ if (this.signedArea >= 0) | ||
} | ||
/** Cut this polygon along a line, and return multiple parts. */ | ||
cut(line) { | ||
@@ -1238,2 +1287,3 @@ const t = this.radius / line.length * 10; | ||
} | ||
/** Checks if two polygons p1 and p2 collide. */ | ||
static collision(p1, p2) { | ||
@@ -1260,2 +1310,3 @@ if (p1.points.some((q) => p2.contains(q))) | ||
} | ||
/** Creates a regular polygon. */ | ||
static regular(n, radius = 1) { | ||
@@ -1267,2 +1318,3 @@ const da = TWO_PI / n; | ||
} | ||
/** Interpolates the points of two polygons */ | ||
static interpolate(p1, p2, t = 0.5) { | ||
@@ -1298,2 +1350,7 @@ const points = p1.points.map( | ||
} | ||
// --------------------------------------------------------------------------- | ||
/** | ||
* Checks if a point p lies inside this polygon, by using a ray-casting | ||
* algorithm and calculating the number of intersections. | ||
*/ | ||
contains(p) { | ||
@@ -1338,8 +1395,11 @@ let inside = false; | ||
} | ||
/** Center this polygon on a given point or the origin */ | ||
centerAt(on = ORIGIN) { | ||
return this.translate(on.subtract(this.centroid)); | ||
} | ||
// --------------------------------------------------------------------------- | ||
transform(m) { | ||
return new this.constructor(...this.points.map((p) => p.transform(m))); | ||
} | ||
/** Rotates this polygon by a given angle (in radians), optionally around point `center`. */ | ||
rotate(a, center = ORIGIN) { | ||
@@ -1398,2 +1458,3 @@ if (nearlyEquals7(a, 0)) | ||
} | ||
/** @returns {Segment[]} */ | ||
get edges() { | ||
@@ -1469,5 +1530,7 @@ const edges = []; | ||
} | ||
/** Checks if `a` and `b` are roughly equivalent (by default, within one degree of eachother) */ | ||
static equals(a, b, precision = Math.PI / 360) { | ||
return nearlyEquals8(a.rad, b.rad, precision); | ||
} | ||
/** The size, in radians, of this angle. */ | ||
get rad() { | ||
@@ -1481,8 +1544,11 @@ const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x); | ||
} | ||
/** The size, in degrees, of this angle. */ | ||
get deg() { | ||
return this.rad * 180 / Math.PI; | ||
} | ||
/** Checks if this angle is right-angled. */ | ||
get isRight() { | ||
return nearlyEquals8(this.rad, Math.PI / 2, Math.PI / 360); | ||
} | ||
/** The bisector of this angle. */ | ||
get bisector() { | ||
@@ -1502,11 +1568,16 @@ if (this.b.equals(this.a)) | ||
} | ||
/** Returns the smaller one of this and its supplementary angle. */ | ||
get sup() { | ||
return this.rad < Math.PI ? this : new Angle(this.c, this.b, this.a); | ||
} | ||
/** Returns the Arc element corresponding to this angle. */ | ||
get arc() { | ||
return new Arc(this.b, this.a, this.rad); | ||
} | ||
// --------------------------------------------------------------------------- | ||
/** Radius of the arc or sector representing this angle. */ | ||
get radius() { | ||
return 24 + 20 * (1 - clamp4(this.rad, 0, Math.PI) / Math.PI); | ||
} | ||
/** Shape object that can be used to draw this angle. */ | ||
shape(filled = true, radius, round) { | ||
@@ -1530,2 +1601,4 @@ if (this.a.equals(this.b) || this.c.equals(this.b)) | ||
} | ||
// --------------------------------------------------------------------------- | ||
// These functions are just included for compatibility with GeoPath | ||
project(p) { | ||
@@ -1543,2 +1616,3 @@ return this.contains(p) ? p : this.shape(true).project(p); | ||
} | ||
// --------------------------------------------------------------------------- | ||
transform(m) { | ||
@@ -1584,2 +1658,3 @@ return new Angle(this.a.transform(m), this.b.transform(m), this.c.transform(m)); | ||
} | ||
/** Creates the smallest rectangle containing all given points. */ | ||
static aroundPoints(points) { | ||
@@ -1610,8 +1685,11 @@ let xMin = Infinity; | ||
} | ||
/** @returns {Segment[]} */ | ||
get edges() { | ||
return this.polygon.edges; | ||
} | ||
/** @returns {Point[]} */ | ||
get points() { | ||
return this.polygon.points; | ||
} | ||
/** A polygon class representing this rectangle. */ | ||
get polygon() { | ||
@@ -1632,2 +1710,3 @@ const b = new Point(this.p.x + this.w, this.p.y); | ||
} | ||
// --------------------------------------------------------------------------- | ||
contains(p, tolerance) { | ||
@@ -1651,5 +1730,7 @@ return isBetween3(p.x, this.p.x, this.p.x + this.w, tolerance) && isBetween3(p.y, this.p.y, this.p.y + this.h, tolerance); | ||
} | ||
// --------------------------------------------------------------------------- | ||
transform(m) { | ||
return this.polygon.transform(m); | ||
} | ||
/** Rotates this rectangle by a given angle (in radians), optionally around point `c`. */ | ||
rotate(a, c = ORIGIN) { | ||
@@ -1682,2 +1763,6 @@ if (nearlyEquals9(a, 0)) | ||
var Bounds = class { | ||
/** | ||
* Use the `errorHandling` option to decide how to deal with cases where the | ||
* min and max values are in the wrong order. | ||
*/ | ||
constructor(xMin, xMax, yMin, yMax, errorHandling) { | ||
@@ -1919,2 +2004,8 @@ this.xMin = xMin; | ||
var Ellipse = class { | ||
/** | ||
* @param c Center of the ellipse | ||
* @param a Major axis | ||
* @param b Minor axis | ||
* @param angle The rotation of the major axis of the ellipse. | ||
*/ | ||
constructor(c, a, b, angle = 0) { | ||
@@ -1943,2 +2034,3 @@ this.c = c; | ||
} | ||
/** Intersection between an ellipse and a line. */ | ||
intersect(line) { | ||
@@ -1956,2 +2048,6 @@ line = line.rotate(-this.angle, this.c); | ||
} | ||
/** | ||
* Creates a new Ellipse. StringLength is the length of string from one foci | ||
* to a point on the circumference, to the other foci. | ||
*/ | ||
static fromFoci(f1, f2, stringLength) { | ||
@@ -1964,2 +2060,3 @@ const c = Point.distance(f1, f2) / 2; | ||
} | ||
// --------------------------------------------------------------------------- | ||
project(p) { | ||
@@ -1983,2 +2080,3 @@ p = p.rotate(-this.angle, this.c); | ||
} | ||
// --------------------------------------------------------------------------- | ||
transform(_m) { | ||
@@ -1985,0 +2083,0 @@ return this; |
{ | ||
"name": "@mathigon/euclid", | ||
"version": "1.1.7", | ||
"version": "1.1.8", | ||
"license": "MIT", | ||
@@ -35,17 +35,17 @@ "homepage": "https://mathigon.io/euclid", | ||
"dependencies": { | ||
"@mathigon/core": "1.1.4", | ||
"@mathigon/fermat": "1.1.4" | ||
"@mathigon/core": "1.1.5", | ||
"@mathigon/fermat": "1.1.5" | ||
}, | ||
"devDependencies": { | ||
"@types/tape": "4.13.2", | ||
"@typescript-eslint/eslint-plugin": "5.47.1", | ||
"@typescript-eslint/parser": "5.47.1", | ||
"esbuild": "0.16.12", | ||
"eslint": "8.31.0", | ||
"eslint-plugin-import": "2.26.0", | ||
"tape": "5.6.1", | ||
"@typescript-eslint/eslint-plugin": "5.50.0", | ||
"@typescript-eslint/parser": "5.50.0", | ||
"esbuild": "0.17.5", | ||
"eslint": "8.33.0", | ||
"eslint-plugin-import": "2.27.5", | ||
"tape": "5.6.3", | ||
"ts-node": "10.9.1", | ||
"tslib": "2.4.1", | ||
"typescript": "4.9.4" | ||
"tslib": "2.5.0", | ||
"typescript": "4.9.5" | ||
} | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
543655
7355
+ Added@mathigon/core@1.1.5(transitive)
+ Added@mathigon/fermat@1.1.5(transitive)
- Removed@mathigon/core@1.1.4(transitive)
- Removed@mathigon/fermat@1.1.4(transitive)
Updated@mathigon/core@1.1.5
Updated@mathigon/fermat@1.1.5