Skip to content

Arman2409/pointscape

Repository files navigation

A collection of functions for working with points in a 2D coordinate system, along with additional utility functions.

CI npm License: MIT

Live demos →

Table of contents


What's new (2.0.0)

This release is 2.0.0 (not 1.8.x) on purpose: nearest now returns null for an empty list, and collision uses true circular distance. Both can require code or tuning changes, so SemVer treats this as major—users on ^1.x stay on 1.x until they upgrade consciously.

  • collision — Euclidean radius vs the old axis-aligned bounds; retune if you depended on the box.
  • nearestnull when no candidates; guard before using the point.
  • collisionInArray — Same semantics as collision; barrel import cycle removed.
  • collision — Optional callback typed as () => void.

See CHANGELOG.md for full notes.


How to use

Use Node 18+. The repo pins Node 20 for development (.nvmrcnvm use recommended).

Install

npm:

npm install pointscape

pnpm / Yarn:

pnpm add pointscape
# or
yarn add pointscape

What ships on npm

The published tarball contains only dist/ (ESM + CJS + types), README, CHANGELOG, and LICENSE—see package.jsonfiles. Import ESM with import or CommonJS with require per your bundler; types are exposed through exports for both.

  1. Default import — one object with every export (larger surface; fine for scripts).
import pointscape from "pointscape";
  1. Named imports (preferred for tree-shaking) — see Types and imports below.

Types and imports (TypeScript)

Use named imports so bundlers can tree-shake unused functions:

import { distance, collision, nearest, Point } from "pointscape";
import type { Bounds, Line, PointType } from "pointscape";

Functions take any { x: number; y: number }; you do not have to allocate a Point class instance. PointType matches instances of Point (the class exported from this package).

Developing

Open a PR against the default branch; CI runs npm ci, tests, and npm run build on every push/PR (see .github/workflows/ci.yml).

git clone https://github.com/Arman2409/pointscape.git
cd pointscape
nvm use   # optional: picks Node from .nvmrc
npm ci
npm test
npm run build

Publishing on npm

  1. Bump version in package.json and update CHANGELOG.md.
  2. npm login with an account that [maintains pointscape**](https://www.npmjs.com/package/pointscape) on the public registry (https://registry.npmjs.org/`).
  3. npm publish — the prepack script rebuilds dist/ first.

Preview tarball contents locally: npm run publish:dry-run.

See also npm files publish guide — only dist/, readme, changelog, and license are published.

Examples

Most of the functions are designed for working with points in a 2D coordinate system.

 import { 
    distance,
    middle,
    angle,
    center,
    perimeter
    } from "pointscape";
 
 const point1 = { x: 0, y: 0 };
 const point2 = { x: 10, y: 10 };

 // Plain { x, y } objects work for all point APIs


 const distanceBetweenPoints = distance(point1, point2); 
 // result: 14.142135623730951


 const middlePoint = middle(point1, point2);
 // result: {x: 5, y: 5}


 const angleBetweenPoints = angle(point1, point2);
 // result: 0.7853981633974483
 

 const point3 = { x: 0, y: 10 }, point4 = { x: 10, y: 0 };

 const perimeterOfPoints = perimeter(
   [point1, point2, point3, point4 ]
 );
 // result: 48.2842712474619

The Point class can also be used for working with the points.

 import { Point } from "pointscape";

 const point1 = new Point(0, 0);
 const point2 = new Point(1, 1);

 const distance = point1.distanceTo(point2);
 // result:  1.4142135623730951

 const angle = point1.angleTo(point2);
 // result:  0.7853981633974483

 // nearestFromPoints follows the same rules as nearest(); empty input yields null.

There are other utility functions as well.

 import { 
    inRange,
    chunk, 
    randomBoolean } from "pointscape";

 //  Helper functions for math 

 const isInTheRange = inRange(1, 0, 10);
 // result: true


 // Helper functions for arrays 

 const chunks = chunk([1, 1, 1, 1], 2);
 // result: [[1, 1], [1, 1]]


 // Helper functions for randomization 

 const randomBool = randomBoolean();
 // result: true or false

The list of available functions

Categories

Points

Geometry

area

perimeter

center

square

rectangle

pentagon

triangle

circleArea

middle

Positioning

distance

positionInCircle

angle

nearest

randomPoint

randomPointInDistance

randomPoints

farest

rotate

inLine

cross

move

lerp

Relationships

collision

collisionInArray

possibleConnections

sort

scale

pointWithoutCollision

Math

degreesToRadians

radiansToDegrees

inRange

roundToPrecision

average

Arrays

intersection

difference

chunk

removeDuplicate

sample

Randomization

randomNumber

randomBoolean

uniqueId

Documentation for the functions

Points

  • distance
  interface Point {
    x: number
    y: number
  }

  (point1: Point, point2: Point) => number

Returns the distance beetween two points, each point is an object with x and y properties.

  • area
  (points: Point[]) => number

Returns the area enclosed by the given points. Takes an array of points as argument, where each point is an object with x and y properties.

  • collision
  (point1: Point, point2: Point, collisionDistance: number, [callback]?: () => void) => boolean

Returns true if the Euclidean distance between the two points is less than or equal to collisionDistance (treat collisionDistance as a non-negative radius for a circle around each position). Optionally invokes callback when a collision is detected.

  • collisionInArray
  (initialPoint: Point, points: Point[], radius: number) => Point[]

Returns every point in points whose distance to initialPoint is within radius, using the same circular rule as collision.

  • positionInCircle
  (point: Point, radius: number, angleInRadians: number) => Point

Returns the x and y coordinates for the current point in the circle, given its center point, radius, and angle.

  • angle
  (point1: Point, point2: Point) => number

Returns the angle formed by the connection of two points.

  • middle
  (point1: Point, point2: Point) => Point

Returns the midpoint between two points.

  • nearest
  (point: Point, points: Point[]) => Point | null

Returns the nearest point to the given point from the array, or null if points is empty.

  • perimeter
  (points: Point[]) => number

Returns the perimeter of the figure formed by the given points.

  • pointWithoutCollision(minX, maxX, minY, maxY, distance, points)
  interface Bounds {
    min: number
    max: number
  }

  (xBounds: Bounds, yBounds: Bounds, distance: number, points: Point[]) => Point | string

Returns a point that doesn't collide with any of the given points within the specified distance, if such a point exists, otherwise returns error string.

  • randomPoint
  ([xBounds]: Bounds, [yBounds]: Bounds) => Point

Returns a random point within the given dimensions, if provided, otherwise in 100 units on both axes.

  • randomPointInDistance
  (point: Point, distance: number) => Point

Returns a random point within the given distance from the specified point.

  • randomPoints
   ([xBounds]: Bounds, [yBounds]: Bounds, quantity: number,) => Point[]

Returns a specified quantity of random points within the given dimensions, if dimensions are provided, otherwise in the range of 100.

  • possibleConnections
  (pointsCount: number) => number

Returns the quantity of possible connections among given quantity of points.

  • circleArea
  (radius: number) => number

Returns the area of the circle given its radius.

  • center
  (points: Point[]) => Point

Returns the center of given points.

  • farest
  (point: Point, points: Point[]) => Point | null

Returns the farthest point from the given point among the given array; null if the array is empty.

  • rotate
  (point: Point, points: Point[], angleInRadians: number) => Point[]

Returns the points rotated around the given point.

  • sort
  (points: Point[], coordinate?: "x" | "y") => Point[]

Mutates points in place (Array.sort) and returns the same array reference. Omit coordinate to sort primarily by x; "y" sorts by y.

  • scale
  (scaleFactorX: number, scaleFactorY: number, points: Point[]) => Point[]

Returns the scaled points.

  • inLine
  interface Line {
    start: Point
    end: Point
  }

  (point: Point, line: Line) => boolean

Returns boolean value indicating whether or not the given coordinates are on line defined by two other points.

  • cross
 (line1: Line, line2: Line) => boolean

Returns boolean value indicating if two lines each defined by two points intersect.

  • move
 (point: Point, xStep: number, yStep: number) => Point

Returns a point of with the new coordinates.

  • lerp
 (point1: Point, point2: Point, t: number) => Point

Returns the linearly interpolated point between point1 and point2 at parameter t (0 = point1, 1 = point2, 0.5 = midpoint). Values of t outside [0, 1] extrapolate beyond the two points.

  • square
 (point: Point, size: number, [direction]: "left" | "right" | "down" | "up" ) => Point[]

Returns an array of points representing a shape of square.Takes four parameters: starting coordinates (x and y), size of square side, and direction which should be one of the values "left", "right", "up", "down".

  • rectangle(point, width, height, [direction])
 (point: Point, width: number, height: number, [direction]: "left" | "right" | "down" | "up" ) => Point[]

Returns vertices of a rectangle starting at point, advancing width then height along the directional path (same directional convention as square).

  • triangle(point, size, [direction])
 (point: Point, size: number, [direction]: "left" | "right" | "down" | "up" ) => Point[]

Returns an array of points representing a shape of triangle.Takes same parameters as square function.

  • pentagon(center, radius, [angle])
 (centerPoint: Point, radius: number, angle?: number) => Point[]

Returns vertices of a pentagon around centerPoint with radius and rotation angle (degrees, default 0).

Math

  • degreesToRadians
 (degrees: number) => number

Converts degrees to radians.

  • radiansToDegrees
 (radians: number) => number

Converts radians to degrees.

  • inRange
 (number: number, min: number, max: number) => boolean

Returns true if the given number is within the specified range.

  • roundToPrecision
 (number: number, precision: -100 | -10 | 0 | 10 | 100 | number) => number

Rounds the number to the given precision.

  • average
 (numbers: number[]) => number

Returns the average of all numbers in an array.

Arrays

  • intersection
 (arr1: any[], arr2: any[]) => any[]

Returns the array of intersection of two arrays.

  • difference
 (arr1: any[], arr2: any[]) => any[]

Returns the array of difference of two arrays.

  • chunk
 (arr: any[], perArr: number) => any[][]

Returns an array splited into chunks based on elements count per chunk.

  • removeDuplicates(arr)
 (arr: any[]) => any[]

Returns the array without duplicates.

  • sample
  (arr: any[], [size]: number[]) => any[]

Returns a random sample from an array with optional size argument for sampling length. If not specified, it returns only one element.

Randomization

  • randomNumber
  (min: number, max: number) => number

Returns a random number within the given range.

  • randomBoolean
  () => boolean

Returns a random boolean value.

  • uniqueId
  ([other ids]: string[]) => string 

Returns a unique ID that's different from the provided IDs, or a random ID if no other IDs are given.

About

NPM package of utility functions for working with points in 2D coordinate system

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors