From 284b3a338e283547ebd3b2966d6c3b3fff49906e Mon Sep 17 00:00:00 2001 From: Dane Hansen Date: Mon, 15 Mar 2021 21:47:43 -0700 Subject: [PATCH] remove instance methods --- README.md | 96 ++++------- danehansen-Point.min.js | 199 ++++++++++++++++++++++- index.html | 93 ++++------- package.json | 8 +- src/Point.js | 175 ++++++++------------ test/test.js | 347 +++++++++++++++------------------------- webpack.config.js | 6 +- 7 files changed, 467 insertions(+), 457 deletions(-) diff --git a/README.md b/README.md index e33e108..3311f3f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,6 @@ -# Point ![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/@danehansen/point.svg) ![npm](https://img.shields.io/npm/dt/@danehansen/point.svg) +# point ![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/@danehansen/point.svg) ![npm](https://img.shields.io/npm/dt/@danehansen/point.svg) -**Class** : public class [Point](https://github.com/danehansen/Point) -**Inheritance** : [Point](https://github.com/danehansen/Point) > Object - -The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis. Mostly based on the AS3 Point class, but with some added features/useless ones removed. +The point library contains a collection of functions for dealing with points with numerical x and y values. ## Installation @@ -13,68 +10,45 @@ The Point object represents a location in a two-dimensional coordinate system, w As a module: - import Point from '@danehansen/point'; + import * as point from '@danehansen/point'; - var p = new Point(50, 75); - p.setTo(25, 75); - var d = Point.distace(p, new Point(5, 20)); + var p1 = {x: 50, y: 75}; + var p2 = point.add(p1, {x: 5, y: 5}); + var d = point.distance(p1, p2); In your browser: - + -## Public Static Methods - -- **distance**(pt1:Point, pt2:Point):Number - [static] Returns the distance between pt1 and pt2. -- **interpolate**(pt1:Point, pt2:Point, f:Number):Point - [static] Determines a point between two specified points. -- **intersection**(aStart:Point, aEnd:Point, bStart:Point, bEnd:Point):Point - [static] Returns a point where to traveling points intersect, or null if never. -- **polar**(len:Number, angle:Number):Point - [static] Converts a pair of polar coordinates to a Cartesian point coordinate. -- **randomPointInCircle**(center:Point, radius:Number):Point - [static] Returns a random point within a given circle. -- **round**(v:Point, increment:Number = 1):Point - [static] Returns a new point with its x and y values rounded to the nearest increment. - -## Public Properties - -- **length**() : Number - [read-only] Gets the length of the line segment from (0,0) to this point. -- **x** : Number - The horizontal coordinate of the point. -- **y** : Number - The vertical coordinate of the point. - -## Public Methods - -- **Point**(x:Number = 0, y:Number = 0) - Creates a new point. -- **add**(v:Point):Point - Adds the coordinates of another point to the coordinates of this point to create a new point. -- **angle**():Number - Returns the angle in radians of this point from (0,0). -- **clone**():Point - Creates a copy of this Point object. -- **copyFrom**(sourcePoint:Point) - Copies all of the point data from the source Point object into the calling Point object. -- **equals**(toCompare:Point):Boolean +## Methods + +- **add**(pt1:Object, pt2:Object):Object +Returns a new point equal to sum of two points. +- **angle**(point:Object):Number +Returns the angle in radians of a point from (0,0). +- **distance**(pt1:Object, pt2:Object):Number + Returns the distance between pt1 and pt2. +- **interpolate**(pt1:Object, pt2:Object, f:Number):Object + Determines a point between two specified points. +- **intersection**(aStart:Object, aEnd:Object, bStart:Object, bEnd:Object):Object + Returns a point where to traveling points intersect, or null if never. +- **isEqual**(pt1:Object, pt2:Object):Boolean Determines whether two points are equal. -- **normalize**(thicknes:Number) - Scales the line segment between (0,0) and the current point to a set length. -- **offset**(dx:Number, dy:Number) - Offsets the Point object by the specified amount. -- **rotate**(angle:Number, center:Point = new Point()) - Rotates the Point object around a center point by the specified angle. -- **setTo**(xa:Number, ya:Number) - Sets the members of Point to the specified values -- **subtract**(v:Point):Boolean - Subtracts the coordinates of another point from the coordinates of this point to create a new point. -- **toString**():String +- **normalize**(point:Object, thicknes:Number) + Returns a new point scaled from the line segment between (0,0) and a point to a set length. +- **polar**(len:Number, angle:Number):Object + Converts a pair of polar coordinates to a Cartesian point coordinate. +- **randomPointInCircle**(center:Object, radius:Number):Object + Returns a random point within a given circle. +- **rotate**(point:Object, angle:Number, center:Object = {x: 0, y: 0}) + Returns a new point rotated around a center point by the specified angle. +- **round**(v:Object, increment:Number = 1):Object + Returns a new point with its x and y values rounded to the nearest increment. +- **toString**(point:Object):String Returns a string that contains the values of the x and y coordinates. diff --git a/danehansen-Point.min.js b/danehansen-Point.min.js index 4309351..601ed5e 100644 --- a/danehansen-Point.min.js +++ b/danehansen-Point.min.js @@ -1 +1,198 @@ -!function(n,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@danehansen/math")):"function"==typeof define&&define.amd?define(["@danehansen/math"],t):"object"==typeof exports?exports.Point=t(require("@danehansen/math")):(n.danehansen=n.danehansen||{},n.danehansen.Point=t(n.danehansen.math))}(this,function(n){return function(n){function t(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return n[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var e={};return t.m=n,t.c=e,t.i=function(n){return n},t.d=function(n,e,r){t.o(n,e)||Object.defineProperty(n,e,{configurable:!1,enumerable:!0,get:r})},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},t.p="",t(t.s=1)}([function(t,e){t.exports=n},function(n,t,e){"use strict";function r(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function n(n,t){for(var e=0;e0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;r(this,n),c.call(this),this.x=t,this.y=e}return o(n,null,[{key:"distance",value:function(n,t){return Math.sqrt(Math.pow(n.x-t.x,2)+Math.pow(n.y-t.y,2))}},{key:"interpolate",value:function(t,e,r){return new n(t.x+(e.x-t.x)*r,t.y+(e.y-t.y)*r)}},{key:"intersection",value:function(t,e,r,o){var i=t.x,u=t.y,a=e.x,c=e.y,s=r.x,f=r.y,h=o.x,y=o.y,l=i-a,x=f-y,d=u-c,p=s-h,v=l*x-d*p;if(0===v)return null;var m=i*c-u*a,b=s*y-f*h;return new n((m*p-l*b)/v,(m*x-d*b)/v)}},{key:"polar",value:function(t,e){return new n(Math.cos(e)*t,Math.sin(e)*t)}},{key:"randomPointInCircle",value:function(t,e){var r={};do{r.x=Math.random()*e*2+t.x-e,r.y=Math.random()*e*2+t.y-e}while(n.distance(r,t)>e);return r}},{key:"round",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return new n((0,i.round)(t.x,e),(0,i.round)(t.y,e))}}]),o(n,[{key:"rotate",value:function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:u,e=Math.sin(n),r=Math.cos(n),o=this.x,i=this.y,a=t.x,c=t.y;o-=a,i-=c,this.x=o*r-i*e+a,this.y=o*e+i*r+c}},{key:"length",get:function(){return n.distance(this,u)}}]),n}(),c=function(){var n=this;this.add=function(t){n.offset(t.x,t.y)},this.angle=function(){return Math.atan2(n.y,n.x)},this.clone=function(){return new a(n.x,n.y)},this.copyFrom=function(t){n.setTo(t.x,t.y)},this.equals=function(t){return n.x===t.x&&n.y===t.y},this.normalize=function(t){var e=t/n.length;n.x*=e,n.y*=e},this.offset=function(t,e){n.x+=t,n.y+=e},this.setTo=function(t,e){n.x=t,n.y=e},this.subtract=function(t){n.x-=t.x,n.y-=t.y},this.toString=function(){return"{x: "+n.x+", y: "+n.y+"}"}};n.exports=a}])}); \ No newline at end of file +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("@danehansen/math")); + else if(typeof define === 'function' && define.amd) + define(["@danehansen/math"], factory); + else if(typeof exports === 'object') + exports["point"] = factory(require("@danehansen/math")); + else + root["danehansen"] = root["danehansen"] || {}, root["danehansen"]["point"] = factory(root["danehansen"]["math"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_0__; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.add = add; +exports.angle = angle; +exports.distance = distance; +exports.interpolate = interpolate; +exports.intersection = intersection; +exports.length = length; +exports.normalize = normalize; +exports.polar = polar; +exports.randomPointInCircle = randomPointInCircle; +exports.rotate = rotate; +exports.round = round; +exports.toString = toString; + +var _math = __webpack_require__(0); + +function add(a, b) { + return { x: a.x + b.x, y: a.y + b.y }; +} + +function angle(point) { + return Math.atan2(point.y, point.x); +} + +function distance(a, b) { + return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); +} + +function interpolate(start, end, amount) { + return { x: start.x + (end.x - start.x) * amount, y: start.y + (end.y - start.y) * amount }; +} + +function intersection(startA, endA, startB, endB) { + var x1 = startA.x; + var y1 = startA.y; + var x2 = endA.x; + var y2 = endA.y; + var x3 = startB.x; + var y3 = startB.y; + var x4 = endB.x; + var y4 = endB.y; + var a = x1 - x2; + var b = y3 - y4; + var c = y1 - y2; + var d = x3 - x4; + var e = a * b - c * d; + if (e === 0) { + return null; + } + var f = x1 * y2 - y1 * x2; + var g = x3 * y4 - y3 * x4; + return { x: (f * d - a * g) / e, y: (f * b - c * g) / e }; +} + +function length(point) { + return distance(point, { x: 0, y: 0 }); +} + +function normalize(point, thickness) { + var l = length(point); + var ratio = thickness / l; + return { x: point.x * ratio, y: point.y * ratio }; +} + +function polar(len, angle) { + return { x: Math.cos(angle) * len, y: Math.sin(angle) * len }; +} + +function randomPointInCircle(center, radius) { + var random = {}; + do { + random.x = Math.random() * radius * 2 + center.x - radius; + random.y = Math.random() * radius * 2 + center.y - radius; + } while (distance(random, center) > radius); + return random; +} + +function rotate(point, angle) { + var center = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { x: 0, y: 0 }; + + var sin = Math.sin(angle); + var cos = Math.cos(angle); + var x = point.x, + y = point.y; + + var centerX = center.x; + var centerY = center.y; + x -= centerX; + y -= centerY; + return { x: x * cos - y * sin + centerX, y: x * sin + y * cos + centerY }; +} + +function round(point) { + var increment = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + + return { x: (0, _math.round)(point.x, increment), y: (0, _math.round)(point.y, increment) }; +} + +function toString(point) { + return '{x: ' + point.x + ', y: ' + point.y + '}'; +} + +/***/ }) +/******/ ]); +}); \ No newline at end of file diff --git a/index.html b/index.html index 63bb8d0..a7fe755 100644 --- a/index.html +++ b/index.html @@ -32,77 +32,52 @@ -

Point npm bundle size (scoped) npm

-

Class : public class Point
-Inheritance : Point > Object

-

The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis. Mostly based on the AS3 Point class, but with some added features/useless ones removed.

+

point npm bundle size (scoped) npm

+

The point library contains a collection of functions for dealing with points with numerical x and y values.

Installation

npm install --save @danehansen/point

Usage

As a module:

-
import Point from '@danehansen/point';
+
import * as point from '@danehansen/point';
 
-var p = new Point(50, 75);
-p.setTo(25, 75);
-var d = Point.distace(p, new Point(5, 20));
+var p1 = {x: 50, y: 75};
+var p2 = point.add(p1, {x: 5, y: 5});
+var d = point.distance(p1, p2);
 

In your browser:

-
<script src='danehansen-Point.min.js'></script>
+
<script src='danehansen-point.min.js'></script>
 <script>
-  var Point = window.danehansen.Point;
-  var p = new Point(3, 4);
-  p.add(new Point(5, 6));
+  var point = window.danehansen.point;
+  var p1 = {x: 50, y: 75};
+  var p2 = point.add(p1, {x: 5, y: 5});
+  var d = point.distance(p1, p2);
 </script>
 
-

Public Static Methods

+

Methods

    -
  • distance(pt1:Point, pt2:Point):Number
    -[static] Returns the distance between pt1 and pt2.
  • -
  • interpolate(pt1:Point, pt2:Point, f:Number):Point
    -[static] Determines a point between two specified points.
  • -
  • intersection(aStart:Point, aEnd:Point, bStart:Point, bEnd:Point):Point
    -[static] Returns a point where to traveling points intersect, or null if never.
  • -
  • polar(len:Number, angle:Number):Point
    -[static] Converts a pair of polar coordinates to a Cartesian point coordinate.
  • -
  • randomPointInCircle(center:Point, radius:Number):Point
    -[static] Returns a random point within a given circle.
  • -
  • round(v:Point, increment:Number = 1):Point
    -[static] Returns a new point with its x and y values rounded to the nearest increment.
  • -
-

Public Properties

-
    -
  • length() : Number
    -[read-only] Gets the length of the line segment from (0,0) to this point.
  • -
  • x : Number
    -The horizontal coordinate of the point.
  • -
  • y : Number
    -The vertical coordinate of the point.
  • -
-

Public Methods

-
    -
  • Point(x:Number = 0, y:Number = 0)
    -Creates a new point.
  • -
  • add(v:Point):Point
    -Adds the coordinates of another point to the coordinates of this point to create a new point.
  • -
  • angle():Number
    -Returns the angle in radians of this point from (0,0).
  • -
  • clone():Point
    -Creates a copy of this Point object.
  • -
  • copyFrom(sourcePoint:Point)
    -Copies all of the point data from the source Point object into the calling Point object.
  • -
  • equals(toCompare:Point):Boolean
    +
  • add(pt1:Object, pt2:Object):Object
    +Returns a new point equal to sum of two points.
  • +
  • angle(point:Object):Number
    +Returns the angle in radians of a point from (0,0).
  • +
  • distance(pt1:Object, pt2:Object):Number
    +Returns the distance between pt1 and pt2.
  • +
  • interpolate(pt1:Object, pt2:Object, f:Number):Object
    +Determines a point between two specified points.
  • +
  • intersection(aStart:Object, aEnd:Object, bStart:Object, bEnd:Object):Object
    +Returns a point where to traveling points intersect, or null if never.
  • +
  • isEqual(pt1:Object, pt2:Object):Boolean
    Determines whether two points are equal.
  • -
  • normalize(thicknes:Number)
    -Scales the line segment between (0,0) and the current point to a set length.
  • -
  • offset(dx:Number, dy:Number)
    -Offsets the Point object by the specified amount.
  • -
  • rotate(angle:Number, center:Point = new Point())
    -Rotates the Point object around a center point by the specified angle.
  • -
  • setTo(xa:Number, ya:Number)
    -Sets the members of Point to the specified values
  • -
  • subtract(v:Point):Boolean
    -Subtracts the coordinates of another point from the coordinates of this point to create a new point.
  • -
  • toString():String
    +
  • normalize(point:Object, thicknes:Number)
    +Returns a new point scaled from the line segment between (0,0) and a point to a set length.
  • +
  • polar(len:Number, angle:Number):Object
    +Converts a pair of polar coordinates to a Cartesian point coordinate.
  • +
  • randomPointInCircle(center:Object, radius:Number):Object
    +Returns a random point within a given circle.
  • +
  • rotate(point:Object, angle:Number, center:Object = {x: 0, y: 0})
    +Returns a new point rotated around a center point by the specified angle.
  • +
  • round(v:Object, increment:Number = 1):Object
    +Returns a new point with its x and y values rounded to the nearest increment.
  • +
  • toString(point:Object):String
    Returns a string that contains the values of the x and y coordinates.
diff --git a/package.json b/package.json index 420a24f..a62a021 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "@danehansen/point", - "version": "0.2.7", + "version": "1.0.0", "description": "point", - "main": "danehansen-Point.min.js", + "main": "danehansen-point.min.js", "scripts": { "buildindex": "package-helpers-buildindex srcHtml=./src/index.html srcReadme=./README.md dest=./index.html", "max": "webpack", @@ -32,10 +32,10 @@ "webpack": "^2.5.0" }, "dependencies": { - "@danehansen/math": "^0.3.3" + "@danehansen/math": "^1.0.0" }, "repository": { "type": "git", - "url": "https://github.com/danehansen/Point" + "url": "https://github.com/danehansen/point" } } diff --git a/src/Point.js b/src/Point.js index f109dfe..59be71d 100644 --- a/src/Point.js +++ b/src/Point.js @@ -1,121 +1,82 @@ -import { round } from '@danehansen/math' +import { round as mathRound } from '@danehansen/math' -const ORIGIN = { x: 0, y: 0 } - -class Point { - static distance(a, b) { - return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)) - } - - static interpolate(start, end, amount) { - return new Point(start.x + (end.x - start.x) * amount, start.y + (end.y - start.y) * amount) - } - - static intersection(startA, endA, startB, endB) { - const x1 = startA.x - const y1 = startA.y - const x2 = endA.x - const y2 = endA.y - const x3 = startB.x - const y3 = startB.y - const x4 = endB.x - const y4 = endB.y - const a = x1 - x2 - const b = y3 - y4 - const c = y1 - y2 - const d = x3 - x4 - const e = a * b - c * d - if (e === 0) { - return null - } - const f = x1 * y2 - y1 * x2 - const g = x3 * y4 - y3 * x4 - return new Point((f * d - a * g) / e, (f * b - c * g) / e) - } - - static polar(len, angle) { - return new Point(Math.cos(angle) * len, Math.sin(angle) * len) - } - - static randomPointInCircle(center, radius) { - const random = {} - do { - random.x = Math.random() * radius * 2 + center.x - radius - random.y = Math.random() * radius * 2 + center.y - radius - } - while(Point.distance(random, center) > radius) - return random - } - - static round(point, increment = 1) { - return new Point(round(point.x, increment), round(point.y, increment)) - } - - constructor(x = 0, y = 0) { - this.x = x - this.y = y - } - - add = (point) => { - this.offset(point.x, point.y) - } - - angle = () => { - return Math.atan2(this.y, this.x) - } +export function add(a, b) { + return {x: a.x + b.x, y: a.y + b.y}; +} - clone = () => { - return new Point(this.x, this.y) - } +export function angle(point) { + return Math.atan2(point.y, point.x); +} - copyFrom = (point) => { - this.setTo(point.x, point.y) - } +export function distance(a, b) { + return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); +} - equals = (point) => { - return this.x === point.x && this.y === point.y - } +export function interpolate(start, end, amount) { + return {x: start.x + (end.x - start.x) * amount, y: start.y + (end.y - start.y) * amount}; +} - get length() { - return Point.distance(this, ORIGIN) - } +export function intersection(startA, endA, startB, endB) { + const x1 = startA.x + const y1 = startA.y + const x2 = endA.x + const y2 = endA.y + const x3 = startB.x + const y3 = startB.y + const x4 = endB.x + const y4 = endB.y + const a = x1 - x2 + const b = y3 - y4 + const c = y1 - y2 + const d = x3 - x4 + const e = a * b - c * d + if (e === 0) { + return null + } + const f = x1 * y2 - y1 * x2 + const g = x3 * y4 - y3 * x4 + return {x: (f * d - a * g) / e, y:(f * b - c * g) / e}; +} - normalize = (thickness) => { - const ratio = thickness / this.length - this.x *= ratio - this.y *= ratio - } +export function length(point) { + return distance(point, { x: 0, y: 0 }); +} - offset = (x, y) => { - this.x += x - this.y += y - } +export function normalize(point, thickness) { + const l = length(point); + const ratio = thickness / l; + return {x: point.x * ratio, y: point.y * ratio}; +} - rotate(angle, center = ORIGIN) { - const sin = Math.sin(angle) - const cos = Math.cos(angle) - let { x, y } = this - const centerX = center.x - const centerY = center.y - x -= centerX - y -= centerY - this.x = x * cos - y * sin + centerX - this.y = x * sin + y * cos + centerY - } +export function polar(len, angle) { + return {x: Math.cos(angle) * len, y: Math.sin(angle) * len}; +} - setTo = (x, y) => { - this.x = x - this.y = y +export function randomPointInCircle(center, radius) { + const random = {} + do { + random.x = Math.random() * radius * 2 + center.x - radius; + random.y = Math.random() * radius * 2 + center.y - radius; } + while(distance(random, center) > radius) + return random; +} - subtract = (point) => { - this.x -= point.x - this.y -= point.y - } +export function rotate(point, angle, center = {x: 0, y: 0}) { + const sin = Math.sin(angle); + const cos = Math.cos(angle); + let { x, y } = point; + const centerX = center.x; + const centerY = center.y; + x -= centerX; + y -= centerY; + return {x: x * cos - y * sin + centerX, y: x * sin + y * cos + centerY}; +} - toString = () => { - return `{x: ${this.x}, y: ${this.y}}` - } +export function round(point, increment = 1) { + return {x: mathRound(point.x, increment), y: mathRound(point.y, increment)}; } -module.exports = Point +export function toString(point) { + return `{x: ${point.x}, y: ${point.y}}` +} diff --git a/test/test.js b/test/test.js index 8aedb0a..5377a36 100644 --- a/test/test.js +++ b/test/test.js @@ -1,4 +1,4 @@ -import Point from "../src/Point"; +import * as point from "../src/point"; import * as math from "@danehansen/math"; import { expect } from "chai"; import fs from "fs"; @@ -11,298 +11,201 @@ function equals(p1, p2) { const TOLERANCE = 0.001; function roughlyEquals(p1, p2) { - equals(Point.round(p1, TOLERANCE), Point.round(p2, TOLERANCE)); + equals(point.round(p1, TOLERANCE), point.round(p2, TOLERANCE)); } -describe("Point", function() { - describe("danehansen-Point.min.js", function() { +describe("point", function() { + describe("danehansen-point.min.js", function() { it("is minified", function() { const min = fs.readFileSync( - path.join(__dirname, "../danehansen-Point.min.js"), + path.join(__dirname, "../danehansen-point.min.js"), "utf8" ); expect(min.match(/\n/g)).to.be.null; }); }); - describe("constructor", function() { - it("initiates x and y as 0 with no arguments", function() { - const p = new Point(); - equals(p, { x: 0, y: 0 }); - }); - - it("initiates x and y as arguments", function() { - equals(new Point(3, 5), { x: 3, y: 5 }); - }); - }); - describe("add", function() { - it("adds another point onto self", function() { - let a = new Point(); - let b = new Point(3, 5); - a.add(b); - equals(a, b); - - a = new Point(-4, -3); - b = new Point(1, 1); - a.add(b); - equals(a, { x: -3, y: -2 }); + it("returns new point of two added together", function() { + let a = {x: 0, y: 0}; + let b = {x: 3, y: 5}; + let c = point.add(a, b); + equals(b, c); + + a = {x: -4,y: -3}; + b = {x: 1, y: 1}; + c = point.add(a, b); + equals(c, { x: -3, y: -2 }); }); }); describe("angle", function() { it("finds angle of a point reletive to 0, 0", function() { - expect(new Point(0, 1).angle()).to.equal(Math.PI * 0.5); - expect(new Point(1, 0).angle()).to.equal(0); - expect(new Point(-1, 0).angle()).to.equal(Math.PI); - expect(new Point(0, -1).angle()).to.equal(Math.PI * -0.5); + expect(point.angle({x:0, y:1})).to.equal(Math.PI * 0.5); + expect(point.angle({x:1, y:0})).to.equal(0); + expect(point.angle({x:-1, y:0})).to.equal(Math.PI); + expect(point.angle({x:0, y:-1})).to.equal(Math.PI * -0.5); }); }); - describe("clone", function() { - it("makes copy of self", function() { - const a = new Point(Math.random(), Math.random()); - equals(a.clone(), a); - expect(a.clone()).to.not.equal(a); + describe("distance", function() { + it("finds distance between 2 points", function() { + const pointA = { + x: math.random(-100, 100), + y: math.random(-100, 100) + }; + const dist = math.random(1, 10); + const angle = math.random(Math.PI * 2); + const pointB = { + x: pointA.x + Math.cos(angle) * dist, + y: pointA.y + Math.sin(angle) * dist + }; + const precision = 10000; + expect(math.round(point.distance(pointA, pointB), precision)).to.equal( + math.round(dist, precision) + ); }); }); - describe("copyFrom", function() { - it("sets x and y to another points values", function() { - const a = new Point(Math.random(), Math.random()); - const b = new Point(Math.random(), Math.random()); - a.copyFrom(b); - equals(a, b); - expect(a).to.not.equal(b); + describe("interpolate", function() { + it("finds interpolations between beginning and end points", function() { + const p = point.interpolate({ x: 0, y: 0 }, { x: 0, y: 10 }, 0.25); + equals(p, { x: 0, y: 2.5 }); }); }); - describe("equals", function() { - it("finds when x and y are equal to another point", function() { - const a = new Point(Math.random(), Math.random()); - const b = a.clone(); - equals(a, b); - expect(a).to.not.equal(b); - expect(a.equals(b)).to.equal(true); + describe("intersection", function() { + it("finds the point where two lines intersect", function() { + const startA = {x:1,y:1}; + const endA = {x:3,y:3}; + const startB = {x:1,y:3}; + const endB = {x:3,y:1}; + const p = point.intersection(startA, endA, startB, endB); + equals(p, { x: 2, y: 2 }); }); - it("finds when x and y are not equal to another point", function() { - const a = new Point(Math.random(), Math.random()); - const b = new Point(Math.random(), Math.random()); - expect(a).to.not.deep.equal(b); - expect(a).to.not.equal(b); - expect(a.equals(b)).to.equal(false); + it("finds no intersection between two parallel lines", function() { + const startA = {x:1,y:1}; + const endA = {x:1,y:-1}; + const startB = {x:-1,y:1}; + const endB = {x:-1,y:-1} + expect(point.intersection(startA, endA, startB, endB)).to.equal(null); }); }); describe("length", function() { - it("finds distance to 0, 0", function() { - expect(new Point(0, 5).length).to.equal(5); - expect(new Point(0, -5).length).to.equal(5); - expect(new Point(5, 0).length).to.equal(5); - expect(new Point(-5, 0).length).to.equal(5); + it("finds the point where two lines intersect", function() { }); }); describe("normalize", function() { it("scales length to equal a thickness", function() { - let a = new Point(0, 2); - a.normalize(3); - equals(a, { x: 0, y: 3 }); - expect(a.x).to.equal(0); - expect(a.y).to.equal(3); - - a = new Point(0, -2); - a.normalize(4); - expect(a.x).to.equal(0); - expect(a.y).to.equal(-4); - - a = new Point(-2, 0); - a.normalize(5); - expect(a.x).to.equal(-5); - expect(a.y).to.equal(0); - - a = new Point(2, 0); - a.normalize(6); - expect(a.x).to.equal(6); - expect(a.y).to.equal(0); - }); - }); + let a = {x:0,y:2}; + let b = point.normalize(a, 3); + equals(b, { x: 0, y: 3 }); - describe("offset", function() { - it("adds values onto self", function() { - let a = new Point(); - a.offset(3, 5); - expect(a.x).to.equal(3); - expect(a.y).to.equal(5); - - a = new Point(-4, -3); - a.offset(1, 1); - expect(a.x).to.equal(-3); - expect(a.y).to.equal(-2); - }); - }); + a = {x:0,y:-2}; + b = point.normalize(a, 4); + equals(b, { x: 0, y: -4 }); - describe("rotate", function() { - it("rotates point around center", function() { - const diff = math.random(5, 10); - const origin = new Point( - math.random(-diff, diff, true), - math.random(-diff, diff, true) - ); - const point = new Point(origin.x + diff, origin.y); - - point.rotate(Math.PI * 0.5, origin); - roughlyEquals(point, { x: origin.x, y: origin.y + diff }); - - point.rotate(Math.PI * 0.5, origin); - roughlyEquals(point, { x: origin.x - diff, y: origin.y }); + a = {x:-2,y:0}; + b = point.normalize(a, 5); + equals(b, { x: -5, y: 0 }); - point.rotate(Math.PI * 0.5, origin); - roughlyEquals(point, { x: origin.x, y: origin.y - diff }); - - point.rotate(Math.PI * 0.5, origin); - roughlyEquals(point, { x: origin.x + diff, y: origin.y }); + a = {x:2,y:0}; + b = point.normalize(a, 6); + equals(b, { x: 6, y: 0 }); }); + }); - it("rotates point around origin by default", function() { - const diff = math.random(5, 10); - const point = new Point(diff, 0); - - point.rotate(Math.PI * -0.5); - roughlyEquals(point, { x: 0, y: -diff }); - - point.rotate(Math.PI * -0.5); - roughlyEquals(point, { x: -diff, y: 0 }); - - point.rotate(Math.PI * -0.5); - roughlyEquals(point, { x: 0, y: diff }); + describe("polar", function() { + it("creates new angle from length and angle", function() { + const length = 1; + let angle = 0; + roughlyEquals(point.polar(length, angle), { x: 1, y: 0 }); - point.rotate(Math.PI * -0.5); - roughlyEquals(point, { x: diff, y: 0 }); - }); - }); + angle = Math.PI * 0.5; + roughlyEquals(point.polar(length, angle), { x: 0, y: 1 }); - describe("setTo", function() { - it("sets x and y to values", function() { - const a = new Point(Math.random(), Math.random()); - const x = Math.random(); - const y = Math.random(); - a.setTo(x, y); + angle = Math.PI; + roughlyEquals(point.polar(length, angle), { x: -1, y: 0 }); - expect(a.x).to.equal(x); - expect(a.y).to.equal(y); - }); - }); + angle = Math.PI * 1.5; + roughlyEquals(point.polar(length, angle), { x: 0, y: -1 }); - describe("subtract", function() { - it("subtracts another point from self", function() { - let a = new Point(); - let b = new Point(3, 5); - a.subtract(b); - equals(a, { x: -3, y: -5 }); - - a = new Point(-4, -3); - b = new Point(1, 1); - a.subtract(b); - equals(a, { x: -5, y: -4 }); + angle = Math.PI * 2; + roughlyEquals(point.polar(length, angle), { x: 1, y: 0 }); }); }); - describe("toString", function() { - it("converts point into readable string", function() { - const x = Math.random() * 2 - 1; - const y = Math.random() * 2 - 1; - const regex = new RegExp(`{\\s*x:\\s*${x}\\s*,\\s*y\\s*:\\s*${y}\\s*}`); - expect(regex.test(new Point(x, y).toString())).to.equal(true); + describe("randompointInCircle", function() { + it("makes a random point inside circle", function() { + const center = {x: math.random(-10, 10), y: math.random(-10, 10)}; + const radius = math.random(10); + const random = point.randomPointInCircle(center, radius); + expect(point.distance(center, random)).to.be.below(radius); }); }); - describe("static distance", function() { - it("finds distance between 2 points", function() { - const pointA = { - x: math.random(-100, 100), - y: math.random(-100, 100) - }; - const dist = math.random(1, 10); - const angle = math.random(Math.PI * 2); - const pointB = { - x: pointA.x + Math.cos(angle) * dist, - y: pointA.y + Math.sin(angle) * dist + describe("rotate", function() { + it("rotates point around center", function() { + const diff = math.random(5, 10); + const origin = { + x: math.random(-diff, diff, true), + y: math.random(-diff, diff, true) }; - const precision = 10000; - expect(math.round(Point.distance(pointA, pointB), precision)).to.equal( - math.round(dist, precision) - ); - }); - }); + const a = {x: origin.x + diff, y: origin.y}; - describe("static interpolate", function() { - it("finds interpolations between beginning and end points", function() { - const p = Point.interpolate({ x: 0, y: 0 }, { x: 0, y: 10 }, 0.25); - equals(p, { x: 0, y: 2.5 }); - }); - }); + let b = point.rotate(a, Math.PI * 0.5, origin); + roughlyEquals(b, { x: origin.x, y: origin.y + diff }); - describe("static intersection", function() { - it("finds the point where two lines intersect", function() { - const startA = new Point(1, 1); - const endA = new Point(3, 3); - const startB = new Point(1, 3); - const endB = new Point(3, 1); - const p = Point.intersection(startA, endA, startB, endB); - equals(p, { x: 2, y: 2 }); - }); + b = point.rotate(a, Math.PI * 1, origin); + roughlyEquals(b, { x: origin.x - diff, y: origin.y }); - it("finds no intersection between two parallel lines", function() { - const startA = new Point(1, 1); - const endA = new Point(1, -1); - const startB = new Point(-1, 1); - const endB = new Point(-1, -1); - expect(Point.intersection(startA, endA, startB, endB)).to.equal(null); + b = point.rotate(a, Math.PI * 1.5, origin); + roughlyEquals(b, { x: origin.x, y: origin.y - diff }); + + b = point.rotate(a, Math.PI * 2, origin); + roughlyEquals(b, { x: origin.x + diff, y: origin.y }); }); - }); - describe("static polar", function() { - it("creates new angle from length and angle", function() { - const length = 1; - let angle = 0; - roughlyEquals(Point.polar(length, angle), { x: 1, y: 0 }); + it("returns a point rotated around an origin by default", function() { + const diff = math.random(5, 10); + const a = {x: diff, y: 0}; - angle = Math.PI * 0.5; - roughlyEquals(Point.polar(length, angle), { x: 0, y: 1 }); + let b = point.rotate(a, Math.PI * -0.5); + roughlyEquals(b, { x: 0, y: -diff }); - angle = Math.PI; - roughlyEquals(Point.polar(length, angle), { x: -1, y: 0 }); + b = point.rotate(a, Math.PI * -1); + roughlyEquals(b, { x: -diff, y: 0 }); - angle = Math.PI * 1.5; - roughlyEquals(Point.polar(length, angle), { x: 0, y: -1 }); + b = point.rotate(a, Math.PI * -1.5); + roughlyEquals(b, { x: 0, y: diff }); - angle = Math.PI * 2; - roughlyEquals(Point.polar(length, angle), { x: 1, y: 0 }); + b = point.rotate(a, Math.PI * -2); + roughlyEquals(b, { x: diff, y: 0 }); }); }); - describe("static round", function() { - it("makes a new point with values rounded to nearest increment", function() { - const a = new Point(2.000001, 3.0000001); - const b = Point.round(a, TOLERANCE); + describe("round", function() { + it("returns a new point with values rounded to nearest increment", function() { + const b = point.round({x:2.000001, y:3.0000001}, TOLERANCE); equals(b, { x: 2, y: 3 }); }); - it("makes a new point with values rounded to 1 by default", function() { - const a = new Point(math.random(-100, 100), math.random(-100, 100)); - const b = Point.round(a); + it("returns a new point with values rounded to 1 by default", function() { + const a = {x: math.random(-100, 100), y: math.random(-100, 100)}; + const b = point.round(a); equals(b, { x: Math.round(a.x), y: Math.round(a.y) }); }); }); - describe("static randomPointInCircle", function() { - it("makes a random point inside circle", function() { - const center = new Point(math.random(-10, 10), math.random(-10, 10)); - const radius = math.random(10); - const random = Point.randomPointInCircle(center, radius); - expect(Point.distance(center, random)).to.be.below(radius); + describe("toString", function() { + it("converts point into readable string", function() { + const x = Math.random() * 2 - 1; + const y = Math.random() * 2 - 1; + const regex = new RegExp(`{\\s*x:\\s*${x}\\s*,\\s*y\\s*:\\s*${y}\\s*}`); + expect(regex.test(point.toString({x,y}))).to.equal(true); }); }); }); diff --git a/webpack.config.js b/webpack.config.js index 407a8d9..db026cf 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,6 @@ module.exports = { entry: { - app: './src/Point.js', + app: './src/point.js', }, module: { rules: [ @@ -14,8 +14,8 @@ module.exports = { ], }, output: { - filename: 'danehansen-Point.min.js', - library: ['danehansen', 'Point'], + filename: 'danehansen-point.min.js', + library: ['danehansen', 'point'], libraryTarget: 'umd', }, externals: [