Socket
Socket
Sign inDemoInstall

@mathigon/euclid

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mathigon/euclid - npm Package Compare versions

Comparing version 1.0.7 to 1.0.8

9

dist/angle.d.ts
import { Arc } from './arc';
import { Line } from './line';
import { Point } from './point';
import { Polygon } from './polygon';
import { GeoShape, SimplePoint, TransformMatrix } from './utilities';

@@ -30,6 +31,10 @@ /** Convert angles in radians to degrees. */

get arc(): Arc;
project(): Point;
/** Radius of the arc or sector representing this angle. */
get radius(): number;
/** Shape object that can be used to draw this angle. */
shape(filled?: boolean, radius?: number, round?: boolean): Polygon | Arc;
project(p: Point): Point;
at(): Point;
offset(): number;
contains(): boolean;
contains(p: Point): boolean;
transform(m: TransformMatrix): Angle;

@@ -36,0 +41,0 @@ rotate(a: number, c?: SimplePoint): Angle;

@@ -1,2 +0,1 @@

import { Angle } from './angle';
import { Rectangle } from './rectangle';

@@ -14,3 +13,2 @@ import { GeoElement } from './utilities';

}
export declare function angleSize(angle: Angle, options?: SVGDrawingOptions): number;
export declare function drawSVG(obj: GeoElement, options?: SVGDrawingOptions): string;

@@ -43,3 +43,2 @@ var __defProp = Object.defineProperty;

Triangle: () => Triangle,
angleSize: () => angleSize,
drawCanvas: () => drawCanvas,

@@ -68,3 +67,3 @@ drawSVG: () => drawSVG,

// src/angle.ts
var import_fermat6 = require("@mathigon/fermat");
var import_fermat9 = require("@mathigon/fermat");

@@ -577,113 +576,9 @@ // src/arc.ts

// src/angle.ts
var RAD_TO_DEG = 180 / Math.PI;
var DEG_TO_RAD = Math.PI / 180;
function toDeg(n) {
return n * RAD_TO_DEG;
}
function toRad(n) {
return n * DEG_TO_RAD;
}
var Angle = class {
constructor(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
this.type = "angle";
}
static fromDegrees(val) {
return Angle.fromRadians(val * (Math.PI / 180));
}
static fromRadians(val) {
const p1 = new Point(1, 0);
const p2 = p1.rotate(val);
return new Angle(p1, ORIGIN, p2);
}
get rad() {
const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x);
const phiC = Math.atan2(this.c.y - this.b.y, this.c.x - this.b.x);
let phi = phiC - phiA;
if (phi < 0)
phi += TWO_PI;
return phi;
}
get deg() {
return this.rad * 180 / Math.PI;
}
get isRight() {
return (0, import_fermat6.nearlyEquals)(this.rad, Math.PI / 2, Math.PI / 360);
}
get bisector() {
if (this.b.equals(this.a))
return void 0;
if (this.b.equals(this.c))
return void 0;
const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x);
const phiC = Math.atan2(this.c.y - this.b.y, this.c.x - this.b.x);
let phi = (phiA + phiC) / 2;
if (phiA > phiC)
phi += Math.PI;
const x = Math.cos(phi) + this.b.x;
const y = Math.sin(phi) + this.b.y;
return new Line(this.b, new Point(x, y));
}
get sup() {
return this.rad < Math.PI ? this : new Angle(this.c, this.b, this.a);
}
get arc() {
return new Arc(this.b, this.a, this.rad);
}
project() {
return this.c;
}
at() {
return this.c;
}
offset() {
return 0;
}
contains() {
return false;
}
transform(m) {
return new Angle(this.a.transform(m), this.b.transform(m), this.c.transform(m));
}
rotate(a, c) {
if ((0, import_fermat6.nearlyEquals)(a, 0))
return this;
return new Angle(this.a.rotate(a, c), this.b.rotate(a, c), this.c.rotate(a, c));
}
reflect(l) {
return new Angle(this.a.reflect(l), this.b.reflect(l), this.c.reflect(l));
}
scale(sx, sy = sx) {
return new Angle(this.a.scale(sx, sy), this.b.scale(sx, sy), this.c.scale(sx, sy));
}
shift(x, y = x) {
return new Angle(this.a.shift(x, y), this.b.shift(x, y), this.c.shift(x, y));
}
translate(p) {
return new Angle(this.a.translate(p), this.b.translate(p), this.c.translate(p));
}
equals(_a) {
return false;
}
toString() {
return `angle(${this.a},${this.b},${this.c})`;
}
};
// src/bounds.ts
var import_fermat11 = require("@mathigon/fermat");
// src/rectangle.ts
var import_fermat10 = require("@mathigon/fermat");
// src/polygon.ts
var import_core4 = require("@mathigon/core");
var import_fermat9 = require("@mathigon/fermat");
var import_fermat8 = require("@mathigon/fermat");
// src/boolean.ts
var import_core2 = require("@mathigon/core");
var import_fermat7 = require("@mathigon/fermat");
var import_fermat6 = require("@mathigon/fermat");
var PRECISION = 1e-6;

@@ -707,4 +602,4 @@ function pointAboveOrOnLine(pt, left, right) {

function pointsCompare(p1, p2) {
if ((0, import_fermat7.nearlyEquals)(p1.x, p2.x)) {
return (0, import_fermat7.nearlyEquals)(p1.y, p2.y) ? 0 : p1.y < p2.y ? -1 : 1;
if ((0, import_fermat6.nearlyEquals)(p1.x, p2.x)) {
return (0, import_fermat6.nearlyEquals)(p1.y, p2.y) ? 0 : p1.y < p2.y ? -1 : 1;
}

@@ -730,3 +625,3 @@ return p1.x < p2.x ? -1 : 1;

const axb = adx * bdy - ady * bdx;
if ((0, import_fermat7.nearlyEquals)(axb, 0))
if ((0, import_fermat6.nearlyEquals)(axb, 0))
return false;

@@ -1132,3 +1027,3 @@ const dx = a0.x - b0.x;

var import_core3 = require("@mathigon/core");
var import_fermat8 = require("@mathigon/fermat");
var import_fermat7 = require("@mathigon/fermat");

@@ -1181,8 +1076,8 @@ // src/types.ts

function liesOnSegment(s, p) {
if ((0, import_fermat8.nearlyEquals)(s.p1.x, s.p2.x))
return (0, import_fermat8.isBetween)(p.y, s.p1.y, s.p2.y);
return (0, import_fermat8.isBetween)(p.x, s.p1.x, s.p2.x);
if ((0, import_fermat7.nearlyEquals)(s.p1.x, s.p2.x))
return (0, import_fermat7.isBetween)(p.y, s.p1.y, s.p2.y);
return (0, import_fermat7.isBetween)(p.x, s.p1.x, s.p2.x);
}
function liesOnRay(r, p) {
if ((0, import_fermat8.nearlyEquals)(r.p1.x, r.p2.x))
if ((0, import_fermat7.nearlyEquals)(r.p1.x, r.p2.x))
return (p.y - r.p1.y) / (r.p2.y - r.p1.y) > 0;

@@ -1192,3 +1087,3 @@ return (p.x - r.p1.x) / (r.p2.x - r.p1.x) > 0;

function liesOnArc(a, p) {
return (0, import_fermat8.isBetween)(a.offset(p), 0, 1);
return (0, import_fermat7.isBetween)(a.offset(p), 0, 1);
}

@@ -1201,3 +1096,3 @@ function lineLineIntersection(l1, l2) {

const d = d1x * d2y - d1y * d2x;
if ((0, import_fermat8.nearlyEquals)(d, 0))
if ((0, import_fermat7.nearlyEquals)(d, 0))
return [];

@@ -1216,8 +1111,8 @@ const q1 = l1.p1.x * l1.p2.y - l1.p1.y * l1.p2.x;

return [];
if ((0, import_fermat8.nearlyEquals)(d, 0) && (0, import_fermat8.nearlyEquals)(c1.r, c2.r))
if ((0, import_fermat7.nearlyEquals)(d, 0) && (0, import_fermat7.nearlyEquals)(c1.r, c2.r))
return [];
if ((0, import_fermat8.nearlyEquals)(d, c1.r + c2.r))
if ((0, import_fermat7.nearlyEquals)(d, c1.r + c2.r))
return [new Line(c1.c, c2.c).midpoint];
const a = ((0, import_fermat8.square)(c1.r) - (0, import_fermat8.square)(c2.r) + (0, import_fermat8.square)(d)) / (2 * d);
const b = Math.sqrt((0, import_fermat8.square)(c1.r) - (0, import_fermat8.square)(a));
const a = ((0, import_fermat7.square)(c1.r) - (0, import_fermat7.square)(c2.r) + (0, import_fermat7.square)(d)) / (2 * d);
const b = Math.sqrt((0, import_fermat7.square)(c1.r) - (0, import_fermat7.square)(a));
const px = (c2.c.x - c1.c.x) * a / d + (c2.c.y - c1.c.y) * b / d + c1.c.x;

@@ -1232,7 +1127,7 @@ const py = (c2.c.y - c1.c.y) * a / d - (c2.c.x - c1.c.x) * b / d + c1.c.y;

const dy = l.p2.y - l.p1.y;
const dr2 = (0, import_fermat8.square)(dx) + (0, import_fermat8.square)(dy);
const dr2 = (0, import_fermat7.square)(dx) + (0, import_fermat7.square)(dy);
const cx = c.c.x;
const cy = c.c.y;
const D = (l.p1.x - cx) * (l.p2.y - cy) - (l.p2.x - cx) * (l.p1.y - cy);
const disc = (0, import_fermat8.square)(c.r) * dr2 - (0, import_fermat8.square)(D);
const disc = (0, import_fermat7.square)(c.r) * dr2 - (0, import_fermat7.square)(D);
if (disc < 0)

@@ -1242,3 +1137,3 @@ return [];

const ya = -D * dx / dr2;
if ((0, import_fermat8.nearlyEquals)(disc, 0))
if ((0, import_fermat7.nearlyEquals)(disc, 0))
return [c.c.shift(xa, ya)];

@@ -1276,5 +1171,9 @@ const xb = dx * (dy < 0 ? -1 : 1) * Math.sqrt(disc) / dr2;

if (elements.length > 2) {
return (0, import_core3.flatten)((0, import_fermat8.subsets)(elements, 2).map((e) => intersections(...e)));
return (0, import_core3.flatten)((0, import_fermat7.subsets)(elements, 2).map((e) => intersections(...e)));
}
let [a, b] = elements;
if (isAngle(a))
a = a.shape(true);
if (isAngle(b))
b = b.shape(true);
if (isPolygonLike(b))

@@ -1459,3 +1358,3 @@ [a, b] = [b, a];

rotate(a, center = ORIGIN) {
if ((0, import_fermat9.nearlyEquals)(a, 0))
if ((0, import_fermat8.nearlyEquals)(a, 0))
return this;

@@ -1535,2 +1434,4 @@ const points = this.points.map((p) => p.rotate(a, center));

const radius = Point.distance(center, this.points[0]);
if (isNaN(radius) || radius > Number.MAX_SAFE_INTEGER)
return;
return new Circle(center, radius);

@@ -1547,3 +1448,3 @@ }

const radius = center.distanceFromLine(edges[0]);
return new Circle(center, radius);
return isNaN(radius) ? void 0 : new Circle(center, radius);
}

@@ -1558,3 +1459,126 @@ get orthocenter() {

// src/angle.ts
var RAD_TO_DEG = 180 / Math.PI;
var DEG_TO_RAD = Math.PI / 180;
function toDeg(n) {
return n * RAD_TO_DEG;
}
function toRad(n) {
return n * DEG_TO_RAD;
}
var Angle = class {
constructor(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
this.type = "angle";
}
static fromDegrees(val) {
return Angle.fromRadians(val * (Math.PI / 180));
}
static fromRadians(val) {
const p1 = new Point(1, 0);
const p2 = p1.rotate(val);
return new Angle(p1, ORIGIN, p2);
}
get rad() {
const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x);
const phiC = Math.atan2(this.c.y - this.b.y, this.c.x - this.b.x);
let phi = phiC - phiA;
if (phi < 0)
phi += TWO_PI;
return phi;
}
get deg() {
return this.rad * 180 / Math.PI;
}
get isRight() {
return (0, import_fermat9.nearlyEquals)(this.rad, Math.PI / 2, Math.PI / 360);
}
get bisector() {
if (this.b.equals(this.a))
return void 0;
if (this.b.equals(this.c))
return void 0;
const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x);
const phiC = Math.atan2(this.c.y - this.b.y, this.c.x - this.b.x);
let phi = (phiA + phiC) / 2;
if (phiA > phiC)
phi += Math.PI;
const x = Math.cos(phi) + this.b.x;
const y = Math.sin(phi) + this.b.y;
return new Line(this.b, new Point(x, y));
}
get sup() {
return this.rad < Math.PI ? this : new Angle(this.c, this.b, this.a);
}
get arc() {
return new Arc(this.b, this.a, this.rad);
}
get radius() {
return 24 + 20 * (1 - (0, import_fermat9.clamp)(this.rad, 0, Math.PI) / Math.PI);
}
shape(filled = true, radius, round) {
if (this.a.equals(this.b) || this.c.equals(this.b))
return new Polygon(ORIGIN);
const angled = this.isRight && !round;
if (!radius)
radius = angled ? 20 : this.radius;
const ba = new Segment(this.b, this.a);
const a = ba.at(radius / ba.length);
if (angled) {
const bc = Point.difference(this.c, this.b).unitVector.scale(radius);
if (filled)
return new Polygon(this.b, a, a.add(bc), this.b.add(bc));
return new Polyline(a, a.add(bc), this.b.add(bc));
}
if (filled)
return new Sector(this.b, a, this.rad);
return new Arc(this.b, a, this.rad);
}
project(p) {
return this.contains(p) ? p : this.shape(true).project(p);
}
at() {
return this.c;
}
offset() {
return 0;
}
contains(p) {
return this.shape(true).contains(p);
}
transform(m) {
return new Angle(this.a.transform(m), this.b.transform(m), this.c.transform(m));
}
rotate(a, c) {
if ((0, import_fermat9.nearlyEquals)(a, 0))
return this;
return new Angle(this.a.rotate(a, c), this.b.rotate(a, c), this.c.rotate(a, c));
}
reflect(l) {
return new Angle(this.a.reflect(l), this.b.reflect(l), this.c.reflect(l));
}
scale(sx, sy = sx) {
return new Angle(this.a.scale(sx, sy), this.b.scale(sx, sy), this.c.scale(sx, sy));
}
shift(x, y = x) {
return new Angle(this.a.shift(x, y), this.b.shift(x, y), this.c.shift(x, y));
}
translate(p) {
return new Angle(this.a.translate(p), this.b.translate(p), this.c.translate(p));
}
equals(_a) {
return false;
}
toString() {
return `angle(${this.a},${this.b},${this.c})`;
}
};
// src/bounds.ts
var import_fermat11 = require("@mathigon/fermat");
// src/rectangle.ts
var import_fermat10 = require("@mathigon/fermat");
var Rectangle = class {

@@ -1701,2 +1725,4 @@ constructor(p, w = 1, h = w) {

function drawCanvas(ctx, obj, options = {}) {
if (isAngle(obj))
return drawCanvas(ctx, obj.shape(!!options.fill), options);
if (options.fill)

@@ -1720,5 +1746,6 @@ ctx.fillStyle = options.fill;

ctx.arc(obj.c.x, obj.c.y, obj.r, 0, TWO_PI);
} else if (isPolygon(obj)) {
ctx.moveTo(obj.points[0].x, obj.points[0].y);
for (const p of obj.points.slice(1))
} else if (isPolygonLike(obj)) {
const points = obj.points;
ctx.moveTo(points[0].x, points[0].y);
for (const p of points.slice(1))
ctx.lineTo(p.x, p.y);

@@ -1739,3 +1766,2 @@ ctx.closePath();

var import_core5 = require("@mathigon/core");
var import_fermat12 = require("@mathigon/fermat");
function drawArc(a, b, c) {

@@ -1747,27 +1773,2 @@ const orient = b.x * (c.y - a.y) + a.x * (b.y - c.y) + c.x * (a.y - b.y);

}
function angleSize(angle, options = {}) {
if (angle.isRight && !options.round)
return 20;
return 24 + 20 * (1 - (0, import_fermat12.clamp)(angle.rad, 0, Math.PI) / Math.PI);
}
function drawAngle(angle, options = {}) {
let a = angle.a;
const b = angle.b;
let c = angle.c;
const size = options.size || angleSize(angle, options);
const ba = Point.difference(a, b).unitVector;
const bc = Point.difference(c, b).unitVector;
a = Point.sum(b, ba.scale(size));
c = Point.sum(b, bc.scale(size));
let p = options.fill ? `M${b.x},${b.y}L` : "M";
if (angle.isRight && !options.round) {
const d = Point.sum(a, bc.scale(size));
p += `${a.x},${a.y}L${d.x},${d.y}L${c.x},${c.y}`;
} else {
p += drawArc(a, b, c);
}
if (options.fill)
p += "Z";
return p;
}
function drawPath(...points) {

@@ -1825,3 +1826,4 @@ return `M${points.map((p) => `${p.x},${p.y}`).join("L")}`;

if (isAngle(obj)) {
return drawAngle(obj, options);
const shape = obj.shape(!!options.fill, options.size, options.round);
return drawSVG(shape, options);
}

@@ -1880,3 +1882,3 @@ if (isSegment(obj)) {

// src/ellipse.ts
var import_fermat13 = require("@mathigon/fermat");
var import_fermat12 = require("@mathigon/fermat");
var Ellipse = class {

@@ -1906,3 +1908,3 @@ constructor(c, a, b) {

const C = (px / this.a) ** 2 + (py / this.b) ** 2 - 1;
const points = (0, import_fermat13.quadratic)(A, B, C);
const points = (0, import_fermat12.quadratic)(A, B, C);
return points.map((t) => line.at(t));

@@ -1909,0 +1911,0 @@ }

// src/angle.ts
import { nearlyEquals as nearlyEquals5 } from "@mathigon/fermat";
import { clamp as clamp4, nearlyEquals as nearlyEquals8 } from "@mathigon/fermat";

@@ -510,113 +510,9 @@ // src/arc.ts

// src/angle.ts
var RAD_TO_DEG = 180 / Math.PI;
var DEG_TO_RAD = Math.PI / 180;
function toDeg(n) {
return n * RAD_TO_DEG;
}
function toRad(n) {
return n * DEG_TO_RAD;
}
var Angle = class {
constructor(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
this.type = "angle";
}
static fromDegrees(val) {
return Angle.fromRadians(val * (Math.PI / 180));
}
static fromRadians(val) {
const p1 = new Point(1, 0);
const p2 = p1.rotate(val);
return new Angle(p1, ORIGIN, p2);
}
get rad() {
const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x);
const phiC = Math.atan2(this.c.y - this.b.y, this.c.x - this.b.x);
let phi = phiC - phiA;
if (phi < 0)
phi += TWO_PI;
return phi;
}
get deg() {
return this.rad * 180 / Math.PI;
}
get isRight() {
return nearlyEquals5(this.rad, Math.PI / 2, Math.PI / 360);
}
get bisector() {
if (this.b.equals(this.a))
return void 0;
if (this.b.equals(this.c))
return void 0;
const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x);
const phiC = Math.atan2(this.c.y - this.b.y, this.c.x - this.b.x);
let phi = (phiA + phiC) / 2;
if (phiA > phiC)
phi += Math.PI;
const x = Math.cos(phi) + this.b.x;
const y = Math.sin(phi) + this.b.y;
return new Line(this.b, new Point(x, y));
}
get sup() {
return this.rad < Math.PI ? this : new Angle(this.c, this.b, this.a);
}
get arc() {
return new Arc(this.b, this.a, this.rad);
}
project() {
return this.c;
}
at() {
return this.c;
}
offset() {
return 0;
}
contains() {
return false;
}
transform(m) {
return new Angle(this.a.transform(m), this.b.transform(m), this.c.transform(m));
}
rotate(a, c) {
if (nearlyEquals5(a, 0))
return this;
return new Angle(this.a.rotate(a, c), this.b.rotate(a, c), this.c.rotate(a, c));
}
reflect(l) {
return new Angle(this.a.reflect(l), this.b.reflect(l), this.c.reflect(l));
}
scale(sx, sy = sx) {
return new Angle(this.a.scale(sx, sy), this.b.scale(sx, sy), this.c.scale(sx, sy));
}
shift(x, y = x) {
return new Angle(this.a.shift(x, y), this.b.shift(x, y), this.c.shift(x, y));
}
translate(p) {
return new Angle(this.a.translate(p), this.b.translate(p), this.c.translate(p));
}
equals(_a) {
return false;
}
toString() {
return `angle(${this.a},${this.b},${this.c})`;
}
};
// src/bounds.ts
import { isBetween as isBetween4 } from "@mathigon/fermat";
// src/rectangle.ts
import { isBetween as isBetween3, nearlyEquals as nearlyEquals9 } from "@mathigon/fermat";
// src/polygon.ts
import { last as last2, tabulate } from "@mathigon/core";
import { nearlyEquals as nearlyEquals8 } from "@mathigon/fermat";
import { nearlyEquals as nearlyEquals7 } from "@mathigon/fermat";
// src/boolean.ts
import { last } from "@mathigon/core";
import { nearlyEquals as nearlyEquals6 } from "@mathigon/fermat";
import { nearlyEquals as nearlyEquals5 } from "@mathigon/fermat";
var PRECISION = 1e-6;

@@ -640,4 +536,4 @@ function pointAboveOrOnLine(pt, left, right) {

function pointsCompare(p1, p2) {
if (nearlyEquals6(p1.x, p2.x)) {
return nearlyEquals6(p1.y, p2.y) ? 0 : p1.y < p2.y ? -1 : 1;
if (nearlyEquals5(p1.x, p2.x)) {
return nearlyEquals5(p1.y, p2.y) ? 0 : p1.y < p2.y ? -1 : 1;
}

@@ -663,3 +559,3 @@ return p1.x < p2.x ? -1 : 1;

const axb = adx * bdy - ady * bdx;
if (nearlyEquals6(axb, 0))
if (nearlyEquals5(axb, 0))
return false;

@@ -1065,3 +961,3 @@ const dx = a0.x - b0.x;

import { flatten } from "@mathigon/core";
import { isBetween as isBetween2, nearlyEquals as nearlyEquals7, square as square2, subsets } from "@mathigon/fermat";
import { isBetween as isBetween2, nearlyEquals as nearlyEquals6, square as square2, subsets } from "@mathigon/fermat";

@@ -1114,3 +1010,3 @@ // src/types.ts

function liesOnSegment(s, p) {
if (nearlyEquals7(s.p1.x, s.p2.x))
if (nearlyEquals6(s.p1.x, s.p2.x))
return isBetween2(p.y, s.p1.y, s.p2.y);

@@ -1120,3 +1016,3 @@ return isBetween2(p.x, s.p1.x, s.p2.x);

function liesOnRay(r, p) {
if (nearlyEquals7(r.p1.x, r.p2.x))
if (nearlyEquals6(r.p1.x, r.p2.x))
return (p.y - r.p1.y) / (r.p2.y - r.p1.y) > 0;

@@ -1134,3 +1030,3 @@ return (p.x - r.p1.x) / (r.p2.x - r.p1.x) > 0;

const d = d1x * d2y - d1y * d2x;
if (nearlyEquals7(d, 0))
if (nearlyEquals6(d, 0))
return [];

@@ -1149,5 +1045,5 @@ const q1 = l1.p1.x * l1.p2.y - l1.p1.y * l1.p2.x;

return [];
if (nearlyEquals7(d, 0) && nearlyEquals7(c1.r, c2.r))
if (nearlyEquals6(d, 0) && nearlyEquals6(c1.r, c2.r))
return [];
if (nearlyEquals7(d, c1.r + c2.r))
if (nearlyEquals6(d, c1.r + c2.r))
return [new Line(c1.c, c2.c).midpoint];

@@ -1174,3 +1070,3 @@ const a = (square2(c1.r) - square2(c2.r) + square2(d)) / (2 * d);

const ya = -D * dx / dr2;
if (nearlyEquals7(disc, 0))
if (nearlyEquals6(disc, 0))
return [c.c.shift(xa, ya)];

@@ -1211,2 +1107,6 @@ const xb = dx * (dy < 0 ? -1 : 1) * Math.sqrt(disc) / dr2;

let [a, b] = elements;
if (isAngle(a))
a = a.shape(true);
if (isAngle(b))
b = b.shape(true);
if (isPolygonLike(b))

@@ -1391,3 +1291,3 @@ [a, b] = [b, a];

rotate(a, center = ORIGIN) {
if (nearlyEquals8(a, 0))
if (nearlyEquals7(a, 0))
return this;

@@ -1467,2 +1367,4 @@ const points = this.points.map((p) => p.rotate(a, center));

const radius = Point.distance(center, this.points[0]);
if (isNaN(radius) || radius > Number.MAX_SAFE_INTEGER)
return;
return new Circle(center, radius);

@@ -1479,3 +1381,3 @@ }

const radius = center.distanceFromLine(edges[0]);
return new Circle(center, radius);
return isNaN(radius) ? void 0 : new Circle(center, radius);
}

@@ -1490,3 +1392,126 @@ get orthocenter() {

// src/angle.ts
var RAD_TO_DEG = 180 / Math.PI;
var DEG_TO_RAD = Math.PI / 180;
function toDeg(n) {
return n * RAD_TO_DEG;
}
function toRad(n) {
return n * DEG_TO_RAD;
}
var Angle = class {
constructor(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
this.type = "angle";
}
static fromDegrees(val) {
return Angle.fromRadians(val * (Math.PI / 180));
}
static fromRadians(val) {
const p1 = new Point(1, 0);
const p2 = p1.rotate(val);
return new Angle(p1, ORIGIN, p2);
}
get rad() {
const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x);
const phiC = Math.atan2(this.c.y - this.b.y, this.c.x - this.b.x);
let phi = phiC - phiA;
if (phi < 0)
phi += TWO_PI;
return phi;
}
get deg() {
return this.rad * 180 / Math.PI;
}
get isRight() {
return nearlyEquals8(this.rad, Math.PI / 2, Math.PI / 360);
}
get bisector() {
if (this.b.equals(this.a))
return void 0;
if (this.b.equals(this.c))
return void 0;
const phiA = Math.atan2(this.a.y - this.b.y, this.a.x - this.b.x);
const phiC = Math.atan2(this.c.y - this.b.y, this.c.x - this.b.x);
let phi = (phiA + phiC) / 2;
if (phiA > phiC)
phi += Math.PI;
const x = Math.cos(phi) + this.b.x;
const y = Math.sin(phi) + this.b.y;
return new Line(this.b, new Point(x, y));
}
get sup() {
return this.rad < Math.PI ? this : new Angle(this.c, this.b, this.a);
}
get arc() {
return new Arc(this.b, this.a, this.rad);
}
get radius() {
return 24 + 20 * (1 - clamp4(this.rad, 0, Math.PI) / Math.PI);
}
shape(filled = true, radius, round) {
if (this.a.equals(this.b) || this.c.equals(this.b))
return new Polygon(ORIGIN);
const angled = this.isRight && !round;
if (!radius)
radius = angled ? 20 : this.radius;
const ba = new Segment(this.b, this.a);
const a = ba.at(radius / ba.length);
if (angled) {
const bc = Point.difference(this.c, this.b).unitVector.scale(radius);
if (filled)
return new Polygon(this.b, a, a.add(bc), this.b.add(bc));
return new Polyline(a, a.add(bc), this.b.add(bc));
}
if (filled)
return new Sector(this.b, a, this.rad);
return new Arc(this.b, a, this.rad);
}
project(p) {
return this.contains(p) ? p : this.shape(true).project(p);
}
at() {
return this.c;
}
offset() {
return 0;
}
contains(p) {
return this.shape(true).contains(p);
}
transform(m) {
return new Angle(this.a.transform(m), this.b.transform(m), this.c.transform(m));
}
rotate(a, c) {
if (nearlyEquals8(a, 0))
return this;
return new Angle(this.a.rotate(a, c), this.b.rotate(a, c), this.c.rotate(a, c));
}
reflect(l) {
return new Angle(this.a.reflect(l), this.b.reflect(l), this.c.reflect(l));
}
scale(sx, sy = sx) {
return new Angle(this.a.scale(sx, sy), this.b.scale(sx, sy), this.c.scale(sx, sy));
}
shift(x, y = x) {
return new Angle(this.a.shift(x, y), this.b.shift(x, y), this.c.shift(x, y));
}
translate(p) {
return new Angle(this.a.translate(p), this.b.translate(p), this.c.translate(p));
}
equals(_a) {
return false;
}
toString() {
return `angle(${this.a},${this.b},${this.c})`;
}
};
// src/bounds.ts
import { isBetween as isBetween4 } from "@mathigon/fermat";
// src/rectangle.ts
import { isBetween as isBetween3, nearlyEquals as nearlyEquals9 } from "@mathigon/fermat";
var Rectangle = class {

@@ -1633,2 +1658,4 @@ constructor(p, w = 1, h = w) {

function drawCanvas(ctx, obj, options = {}) {
if (isAngle(obj))
return drawCanvas(ctx, obj.shape(!!options.fill), options);
if (options.fill)

@@ -1652,5 +1679,6 @@ ctx.fillStyle = options.fill;

ctx.arc(obj.c.x, obj.c.y, obj.r, 0, TWO_PI);
} else if (isPolygon(obj)) {
ctx.moveTo(obj.points[0].x, obj.points[0].y);
for (const p of obj.points.slice(1))
} else if (isPolygonLike(obj)) {
const points = obj.points;
ctx.moveTo(points[0].x, points[0].y);
for (const p of points.slice(1))
ctx.lineTo(p.x, p.y);

@@ -1671,3 +1699,2 @@ ctx.closePath();

import { isOneOf } from "@mathigon/core";
import { clamp as clamp4 } from "@mathigon/fermat";
function drawArc(a, b, c) {

@@ -1679,27 +1706,2 @@ const orient = b.x * (c.y - a.y) + a.x * (b.y - c.y) + c.x * (a.y - b.y);

}
function angleSize(angle, options = {}) {
if (angle.isRight && !options.round)
return 20;
return 24 + 20 * (1 - clamp4(angle.rad, 0, Math.PI) / Math.PI);
}
function drawAngle(angle, options = {}) {
let a = angle.a;
const b = angle.b;
let c = angle.c;
const size = options.size || angleSize(angle, options);
const ba = Point.difference(a, b).unitVector;
const bc = Point.difference(c, b).unitVector;
a = Point.sum(b, ba.scale(size));
c = Point.sum(b, bc.scale(size));
let p = options.fill ? `M${b.x},${b.y}L` : "M";
if (angle.isRight && !options.round) {
const d = Point.sum(a, bc.scale(size));
p += `${a.x},${a.y}L${d.x},${d.y}L${c.x},${c.y}`;
} else {
p += drawArc(a, b, c);
}
if (options.fill)
p += "Z";
return p;
}
function drawPath(...points) {

@@ -1757,3 +1759,4 @@ return `M${points.map((p) => `${p.x},${p.y}`).join("L")}`;

if (isAngle(obj)) {
return drawAngle(obj, options);
const shape = obj.shape(!!options.fill, options.size, options.round);
return drawSVG(shape, options);
}

@@ -1904,3 +1907,2 @@ if (isSegment(obj)) {

Triangle,
angleSize,
drawCanvas,

@@ -1907,0 +1909,0 @@ drawSVG,

@@ -64,5 +64,5 @@ import { Circle } from './circle';

readonly type = "triangle";
get circumcircle(): Circle;
get incircle(): Circle;
get circumcircle(): Circle | undefined;
get incircle(): Circle | undefined;
get orthocenter(): Point;
}
{
"name": "@mathigon/euclid",
"version": "1.0.7",
"version": "1.0.8",
"license": "MIT",

@@ -36,12 +36,12 @@ "homepage": "https://mathigon.io/euclid",

"@types/tape": "4.13.2",
"@typescript-eslint/eslint-plugin": "5.8.1",
"@typescript-eslint/parser": "5.8.1",
"esbuild": "0.14.10",
"eslint": "8.6.0",
"eslint-plugin-import": "2.25.3",
"tape": "5.4.0",
"@typescript-eslint/eslint-plugin": "5.10.2",
"@typescript-eslint/parser": "5.10.2",
"esbuild": "0.14.16",
"eslint": "8.8.0",
"eslint-plugin-import": "2.25.4",
"tape": "5.5.0",
"ts-node": "10.4.0",
"tslib": "2.3.1",
"typescript": "4.5.4"
"typescript": "4.5.5"
}
}

@@ -7,6 +7,7 @@ // =============================================================================

import {nearlyEquals} from '@mathigon/fermat';
import {Arc} from './arc';
import {Line} from './line';
import {clamp, nearlyEquals} from '@mathigon/fermat';
import {Arc, Sector} from './arc';
import {Line, Segment} from './line';
import {ORIGIN, Point} from './point';
import {Polygon, Polyline} from './polygon';
import {GeoShape, SimplePoint, TransformMatrix, TWO_PI} from './utilities';

@@ -94,6 +95,34 @@

// ---------------------------------------------------------------------------
/** Radius of the arc or sector representing this angle. */
get radius() {
return 24 + 20 * (1 - clamp(this.rad, 0, Math.PI) / Math.PI);
}
/** Shape object that can be used to draw this angle. */
shape(filled = true, radius?: number, round?: boolean) {
if (this.a.equals(this.b) || this.c.equals(this.b)) return new Polygon(ORIGIN);
const angled = this.isRight && !round;
if (!radius) radius = angled ? 20 : this.radius;
const ba = new Segment(this.b, this.a);
const a = ba.at(radius / ba.length);
if (angled) {
const bc = Point.difference(this.c, this.b).unitVector.scale(radius);
if (filled) return new Polygon(this.b, a, a.add(bc), this.b.add(bc));
return new Polyline(a, a.add(bc), this.b.add(bc));
}
if (filled) return new Sector(this.b, a, this.rad);
return new Arc(this.b, a, this.rad);
}
// ---------------------------------------------------------------------------
// These functions are just included for compatibility with GeoPath
project() {
return this.c;
project(p: Point) {
return this.contains(p) ? p : this.shape(true).project(p);
}

@@ -109,4 +138,4 @@

contains() {
return false;
contains(p: Point) {
return this.shape(true).contains(p);
}

@@ -113,0 +142,0 @@

@@ -7,4 +7,3 @@ // =============================================================================

// / <reference lib="dom" />
import {isCircle, isPolygon, isPolyline, isSegment} from './types';
import {isAngle, isCircle, isPolygonLike, isPolyline, isSegment} from './types';
import {GeoElement, TWO_PI} from './utilities';

@@ -26,4 +25,5 @@

export function drawCanvas(ctx: CanvasRenderingContext2D, obj: GeoElement,
options: CanvasDrawingOptions = {}) {
export function drawCanvas(ctx: CanvasRenderingContext2D, obj: GeoElement, options: CanvasDrawingOptions = {}): void {
if (isAngle(obj)) return drawCanvas(ctx, obj.shape(!!options.fill), options);
if (options.fill) ctx.fillStyle = options.fill;

@@ -48,5 +48,6 @@ if (options.opacity) ctx.globalAlpha = options.opacity;

} else if (isPolygon(obj)) {
ctx.moveTo(obj.points[0].x, obj.points[0].y);
for (const p of obj.points.slice(1)) ctx.lineTo(p.x, p.y);
} else if (isPolygonLike(obj)) {
const points = obj.points;
ctx.moveTo(points[0].x, points[0].y);
for (const p of points.slice(1)) ctx.lineTo(p.x, p.y);
ctx.closePath();

@@ -59,3 +60,3 @@

// TODO Support for Line, Ray, Arc, Sector, Angle and Rectangle objects
// TODO Support for Line, Ray, Arc and Sector objects

@@ -62,0 +63,0 @@ if (options.fill) ctx.fill();

@@ -8,4 +8,2 @@ // =============================================================================

import {isOneOf} from '@mathigon/core';
import {clamp} from '@mathigon/fermat';
import {Angle} from './angle';
import {Arc} from './arc';

@@ -44,33 +42,2 @@ import {intersections} from './intersection';

export function angleSize(angle: Angle, options: SVGDrawingOptions = {}) {
if (angle.isRight && !options.round) return 20;
return 24 + 20 * (1 - clamp(angle.rad, 0, Math.PI) / Math.PI);
}
function drawAngle(angle: Angle, options: SVGDrawingOptions = {}) {
let a = angle.a;
const b = angle.b;
let c = angle.c;
const size = options.size || angleSize(angle, options);
const ba = Point.difference(a, b).unitVector;
const bc = Point.difference(c, b).unitVector;
a = Point.sum(b, ba.scale(size));
c = Point.sum(b, bc.scale(size));
let p = options.fill ? `M${b.x},${b.y}L` : 'M';
if (angle.isRight && !options.round) {
const d = Point.sum(a, bc.scale(size));
p += `${a.x},${a.y}L${d.x},${d.y}L${c.x},${c.y}`;
} else {
p += drawArc(a, b, c);
}
if (options.fill) p += 'Z';
return p;
}
function drawPath(...points: Point[]) {

@@ -146,6 +113,7 @@ return `M${points.map(p => `${p.x},${p.y}`).join('L')}`;

export function drawSVG(obj: GeoElement, options: SVGDrawingOptions = {}) {
export function drawSVG(obj: GeoElement, options: SVGDrawingOptions = {}): string {
if (isAngle(obj)) {
return drawAngle(obj, options);
const shape = obj.shape(!!options.fill, options.size, options.round);
return drawSVG(shape, options);
}

@@ -152,0 +120,0 @@

@@ -13,3 +13,3 @@ // =============================================================================

import {Point} from './point';
import {isArc, isCircle, isLineLike, isPolygonLike, isRay, isSegment} from './types';
import {isAngle, isArc, isCircle, isLineLike, isPolygonLike, isRay, isSegment} from './types';
import {GeoShape} from './utilities';

@@ -143,2 +143,4 @@

if (isAngle(a)) a = a.shape(true);
if (isAngle(b)) b = b.shape(true);
if (isPolygonLike(b)) [a, b] = [b, a];

@@ -145,0 +147,0 @@

@@ -334,2 +334,3 @@ // =============================================================================

if (isNaN(radius) || radius > Number.MAX_SAFE_INTEGER) return;
return new Circle(center, radius);

@@ -350,3 +351,3 @@ }

return new Circle(center, radius);
return isNaN(radius) ? undefined : new Circle(center, radius);
}

@@ -353,0 +354,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc