Returns:
diff --git a/docs/Box.html b/docs/Box.html index 7ac75e2d..c9427128 100644 --- a/docs/Box.html +++ b/docs/Box.html @@ -24,7 +24,7 @@
new BoxSource:
@@ -332,7 +332,7 @@ boxSource:
@@ -396,7 +396,7 @@ centerSource:
@@ -460,7 +460,7 @@ heightSource:
@@ -524,7 +524,7 @@ highSource:
@@ -588,7 +588,7 @@ lowSource:
@@ -652,7 +652,7 @@ maxSource:
@@ -716,7 +716,7 @@ widthSource:
@@ -780,7 +780,7 @@ xmaxSource:
@@ -854,7 +854,7 @@ xminSource:
@@ -928,7 +928,7 @@ ymaxSource:
@@ -1002,7 +1002,7 @@ yminSource:
@@ -1086,7 +1086,7 @@ cloneSource:
@@ -1140,6 +1140,162 @@ Returns:
+
centerSource:
@@ -460,7 +460,7 @@ heightSource:
@@ -524,7 +524,7 @@ highSource:
@@ -588,7 +588,7 @@ lowSource:
@@ -652,7 +652,7 @@ maxSource:
@@ -716,7 +716,7 @@ widthSource:
@@ -780,7 +780,7 @@ xmaxSource:
@@ -854,7 +854,7 @@ xminSource:
@@ -928,7 +928,7 @@ ymaxSource:
@@ -1002,7 +1002,7 @@ yminSource:
@@ -1086,7 +1086,7 @@ cloneSource:
@@ -1140,6 +1140,162 @@ Returns:
+
highSource:
@@ -588,7 +588,7 @@ lowSource:
@@ -652,7 +652,7 @@ maxSource:
@@ -716,7 +716,7 @@ widthSource:
@@ -780,7 +780,7 @@ xmaxSource:
@@ -854,7 +854,7 @@ xminSource:
@@ -928,7 +928,7 @@ ymaxSource:
@@ -1002,7 +1002,7 @@ yminSource:
@@ -1086,7 +1086,7 @@ cloneSource:
@@ -1140,6 +1140,162 @@ Returns:
+
maxSource:
@@ -716,7 +716,7 @@ widthSource:
@@ -780,7 +780,7 @@ xmaxSource:
@@ -854,7 +854,7 @@ xminSource:
@@ -928,7 +928,7 @@ ymaxSource:
@@ -1002,7 +1002,7 @@ yminSource:
@@ -1086,7 +1086,7 @@ cloneSource:
@@ -1140,6 +1140,162 @@ Returns:
+
xmaxSource:
@@ -854,7 +854,7 @@ xminSource:
@@ -928,7 +928,7 @@ ymaxSource:
@@ -1002,7 +1002,7 @@ yminSource:
@@ -1086,7 +1086,7 @@ cloneSource:
@@ -1140,6 +1140,162 @@ Returns:
+
ymaxSource:
@@ -1002,7 +1002,7 @@ yminSource:
@@ -1086,7 +1086,7 @@ cloneSource:
@@ -1140,6 +1140,162 @@ Returns:
+
cloneSource:
@@ -1140,6 +1140,162 @@ Returns:
+
contains(shape) → {boolean}
+ + + + + +-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- Source: +
- + classes/box.js, line 253 +
+
+
+
+
+
+
+
+
Parameters:
+ + +Name | + + +Type | + + + + + +Description | +
---|---|---|
shape |
+
+
+
+
+
+AnyShape
+
+
+
+ |
+
+
+
+
+
+ + test shape + + | +
Returns:
+ + + +-
+
- + Type: + +
-
+
+
boolean
+ + +
+
equal_toSource:
@@ -1346,7 +1502,7 @@ intersectSource:
@@ -1502,7 +1658,7 @@ less_thanSource:
@@ -1662,7 +1818,7 @@ mergeSource:
@@ -1818,7 +1974,7 @@ not_inte
Source:
@@ -1975,7 +2131,7 @@ rotateSource:
@@ -2168,7 +2324,7 @@ setSource:
@@ -2381,7 +2537,7 @@ svgSource:
@@ -2537,7 +2693,7 @@ toPointsSource:
@@ -2641,7 +2797,7 @@ toSegments<
Source:
@@ -2746,7 +2902,7 @@ transformSource:
@@ -2871,7 +3027,7 @@ Returns:
diff --git a/docs/Circle.html b/docs/Circle.html
index 64ef53ed..6a43af9c 100644
--- a/docs/Circle.html
+++ b/docs/Circle.html
@@ -24,7 +24,7 @@
@@ -1788,7 +1788,7 @@ Returns:
diff --git a/docs/CircularLinkedList.html b/docs/CircularLinkedList.html
index 4e6d02cb..d3ffeaa9 100644
--- a/docs/CircularLinkedList.html
+++ b/docs/CircularLinkedList.html
@@ -24,7 +24,7 @@
@@ -664,7 +664,7 @@ Returns:
diff --git a/docs/DE9IM.html b/docs/DE9IM.html
index 529aa9f5..dc20a311 100644
--- a/docs/DE9IM.html
+++ b/docs/DE9IM.html
@@ -24,7 +24,7 @@
@@ -1507,7 +1507,7 @@ Returns:
diff --git a/docs/Edge.html b/docs/Edge.html
index ec2a6815..7918238a 100644
--- a/docs/Edge.html
+++ b/docs/Edge.html
@@ -24,7 +24,7 @@
@@ -1819,7 +1819,7 @@ Parameters:
diff --git a/docs/Errors.html b/docs/Errors.html
index 90108bd5..c6bde709 100644
--- a/docs/Errors.html
+++ b/docs/Errors.html
@@ -24,7 +24,7 @@
@@ -426,7 +426,7 @@ (static)
diff --git a/docs/Face.html b/docs/Face.html
index 3aafa87b..bb2a1342 100644
--- a/docs/Face.html
+++ b/docs/Face.html
@@ -24,7 +24,7 @@
@@ -2343,7 +2343,7 @@ Returns:
diff --git a/docs/Inversion.html b/docs/Inversion.html
index 5236a32c..216d2b83 100644
--- a/docs/Inversion.html
+++ b/docs/Inversion.html
@@ -24,7 +24,7 @@
@@ -232,7 +232,7 @@ Classes
diff --git a/docs/Line.html b/docs/Line.html
index bc683c5b..24726c29 100644
--- a/docs/Line.html
+++ b/docs/Line.html
@@ -24,7 +24,7 @@
@@ -2629,7 +2629,7 @@ Returns:
diff --git a/docs/LinkedList.html b/docs/LinkedList.html
index 1b3935d8..3d7e479f 100644
--- a/docs/LinkedList.html
+++ b/docs/LinkedList.html
@@ -24,7 +24,7 @@
@@ -1094,7 +1094,7 @@ Returns:
diff --git a/docs/Matrix.html b/docs/Matrix.html
index de61c7d6..7ee25849 100644
--- a/docs/Matrix.html
+++ b/docs/Matrix.html
@@ -24,7 +24,7 @@
@@ -1613,7 +1613,7 @@ Returns:
diff --git a/docs/Multiline.html b/docs/Multiline.html
index 98308f18..aec92f0f 100644
--- a/docs/Multiline.html
+++ b/docs/Multiline.html
@@ -24,7 +24,7 @@
@@ -1849,7 +1849,7 @@ Returns:
diff --git a/docs/PlanarSet.html b/docs/PlanarSet.html
index d57361fa..50db8074 100644
--- a/docs/PlanarSet.html
+++ b/docs/PlanarSet.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ Methods
- add(shape) → {PlanarSet}
+ add(entry) → {PlanarSet}
@@ -265,7 +265,7 @@ addSource:
@@ -309,13 +309,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
shape to be added, should have valid box property
+Another option to transfer as an object {key: Box, value: AnyShape}
@@ -421,7 +425,7 @@ clearSource:
@@ -461,7 +465,7 @@ cleardelete(shape) → {boolean}
+ delete(entry) → {boolean}
@@ -504,7 +508,7 @@ deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
less_thanSource:
@@ -1662,7 +1818,7 @@ mergeSource:
@@ -1818,7 +1974,7 @@ not_inte
Source:
@@ -1975,7 +2131,7 @@ rotateSource:
@@ -2168,7 +2324,7 @@ setSource:
@@ -2381,7 +2537,7 @@ svgSource:
@@ -2537,7 +2693,7 @@ toPointsSource:
@@ -2641,7 +2797,7 @@ toSegments<
Source:
@@ -2746,7 +2902,7 @@ transformSource:
@@ -2871,7 +3027,7 @@ Returns:
diff --git a/docs/Circle.html b/docs/Circle.html
index 64ef53ed..6a43af9c 100644
--- a/docs/Circle.html
+++ b/docs/Circle.html
@@ -24,7 +24,7 @@
@@ -1788,7 +1788,7 @@ Returns:
diff --git a/docs/CircularLinkedList.html b/docs/CircularLinkedList.html
index 4e6d02cb..d3ffeaa9 100644
--- a/docs/CircularLinkedList.html
+++ b/docs/CircularLinkedList.html
@@ -24,7 +24,7 @@
@@ -664,7 +664,7 @@ Returns:
diff --git a/docs/DE9IM.html b/docs/DE9IM.html
index 529aa9f5..dc20a311 100644
--- a/docs/DE9IM.html
+++ b/docs/DE9IM.html
@@ -24,7 +24,7 @@
@@ -1507,7 +1507,7 @@ Returns:
diff --git a/docs/Edge.html b/docs/Edge.html
index ec2a6815..7918238a 100644
--- a/docs/Edge.html
+++ b/docs/Edge.html
@@ -24,7 +24,7 @@
@@ -1819,7 +1819,7 @@ Parameters:
diff --git a/docs/Errors.html b/docs/Errors.html
index 90108bd5..c6bde709 100644
--- a/docs/Errors.html
+++ b/docs/Errors.html
@@ -24,7 +24,7 @@
@@ -426,7 +426,7 @@ (static)
diff --git a/docs/Face.html b/docs/Face.html
index 3aafa87b..bb2a1342 100644
--- a/docs/Face.html
+++ b/docs/Face.html
@@ -24,7 +24,7 @@
@@ -2343,7 +2343,7 @@ Returns:
diff --git a/docs/Inversion.html b/docs/Inversion.html
index 5236a32c..216d2b83 100644
--- a/docs/Inversion.html
+++ b/docs/Inversion.html
@@ -24,7 +24,7 @@
@@ -232,7 +232,7 @@ Classes
diff --git a/docs/Line.html b/docs/Line.html
index bc683c5b..24726c29 100644
--- a/docs/Line.html
+++ b/docs/Line.html
@@ -24,7 +24,7 @@
@@ -2629,7 +2629,7 @@ Returns:
diff --git a/docs/LinkedList.html b/docs/LinkedList.html
index 1b3935d8..3d7e479f 100644
--- a/docs/LinkedList.html
+++ b/docs/LinkedList.html
@@ -24,7 +24,7 @@
@@ -1094,7 +1094,7 @@ Returns:
diff --git a/docs/Matrix.html b/docs/Matrix.html
index de61c7d6..7ee25849 100644
--- a/docs/Matrix.html
+++ b/docs/Matrix.html
@@ -24,7 +24,7 @@
@@ -1613,7 +1613,7 @@ Returns:
diff --git a/docs/Multiline.html b/docs/Multiline.html
index 98308f18..aec92f0f 100644
--- a/docs/Multiline.html
+++ b/docs/Multiline.html
@@ -24,7 +24,7 @@
@@ -1849,7 +1849,7 @@ Returns:
diff --git a/docs/PlanarSet.html b/docs/PlanarSet.html
index d57361fa..50db8074 100644
--- a/docs/PlanarSet.html
+++ b/docs/PlanarSet.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ Methods
- add(shape) → {PlanarSet}
+ add(entry) → {PlanarSet}
@@ -265,7 +265,7 @@ addSource:
@@ -309,13 +309,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
shape to be added, should have valid box property
+Another option to transfer as an object {key: Box, value: AnyShape}
@@ -421,7 +425,7 @@ clearSource:
@@ -461,7 +465,7 @@ cleardelete(shape) → {boolean}
+ delete(entry) → {boolean}
@@ -504,7 +508,7 @@ deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
mergeSource:
@@ -1818,7 +1974,7 @@ not_inte
Source:
@@ -1975,7 +2131,7 @@ rotateSource:
@@ -2168,7 +2324,7 @@ setSource:
@@ -2381,7 +2537,7 @@ svgSource:
@@ -2537,7 +2693,7 @@ toPointsSource:
@@ -2641,7 +2797,7 @@ toSegments<
Source:
@@ -2746,7 +2902,7 @@ transformSource:
@@ -2871,7 +3027,7 @@ Returns:
diff --git a/docs/Circle.html b/docs/Circle.html
index 64ef53ed..6a43af9c 100644
--- a/docs/Circle.html
+++ b/docs/Circle.html
@@ -24,7 +24,7 @@
@@ -1788,7 +1788,7 @@ Returns:
diff --git a/docs/CircularLinkedList.html b/docs/CircularLinkedList.html
index 4e6d02cb..d3ffeaa9 100644
--- a/docs/CircularLinkedList.html
+++ b/docs/CircularLinkedList.html
@@ -24,7 +24,7 @@
@@ -664,7 +664,7 @@ Returns:
diff --git a/docs/DE9IM.html b/docs/DE9IM.html
index 529aa9f5..dc20a311 100644
--- a/docs/DE9IM.html
+++ b/docs/DE9IM.html
@@ -24,7 +24,7 @@
@@ -1507,7 +1507,7 @@ Returns:
diff --git a/docs/Edge.html b/docs/Edge.html
index ec2a6815..7918238a 100644
--- a/docs/Edge.html
+++ b/docs/Edge.html
@@ -24,7 +24,7 @@
@@ -1819,7 +1819,7 @@ Parameters:
diff --git a/docs/Errors.html b/docs/Errors.html
index 90108bd5..c6bde709 100644
--- a/docs/Errors.html
+++ b/docs/Errors.html
@@ -24,7 +24,7 @@
@@ -426,7 +426,7 @@ (static)
diff --git a/docs/Face.html b/docs/Face.html
index 3aafa87b..bb2a1342 100644
--- a/docs/Face.html
+++ b/docs/Face.html
@@ -24,7 +24,7 @@
@@ -2343,7 +2343,7 @@ Returns:
diff --git a/docs/Inversion.html b/docs/Inversion.html
index 5236a32c..216d2b83 100644
--- a/docs/Inversion.html
+++ b/docs/Inversion.html
@@ -24,7 +24,7 @@
@@ -232,7 +232,7 @@ Classes
diff --git a/docs/Line.html b/docs/Line.html
index bc683c5b..24726c29 100644
--- a/docs/Line.html
+++ b/docs/Line.html
@@ -24,7 +24,7 @@
@@ -2629,7 +2629,7 @@ Returns:
diff --git a/docs/LinkedList.html b/docs/LinkedList.html
index 1b3935d8..3d7e479f 100644
--- a/docs/LinkedList.html
+++ b/docs/LinkedList.html
@@ -24,7 +24,7 @@
@@ -1094,7 +1094,7 @@ Returns:
diff --git a/docs/Matrix.html b/docs/Matrix.html
index de61c7d6..7ee25849 100644
--- a/docs/Matrix.html
+++ b/docs/Matrix.html
@@ -24,7 +24,7 @@
@@ -1613,7 +1613,7 @@ Returns:
diff --git a/docs/Multiline.html b/docs/Multiline.html
index 98308f18..aec92f0f 100644
--- a/docs/Multiline.html
+++ b/docs/Multiline.html
@@ -24,7 +24,7 @@
@@ -1849,7 +1849,7 @@ Returns:
diff --git a/docs/PlanarSet.html b/docs/PlanarSet.html
index d57361fa..50db8074 100644
--- a/docs/PlanarSet.html
+++ b/docs/PlanarSet.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ Methods
- add(shape) → {PlanarSet}
+ add(entry) → {PlanarSet}
@@ -265,7 +265,7 @@ addSource:
@@ -309,13 +309,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
shape to be added, should have valid box property
+Another option to transfer as an object {key: Box, value: AnyShape}
@@ -421,7 +425,7 @@ clearSource:
@@ -461,7 +465,7 @@ cleardelete(shape) → {boolean}
+ delete(entry) → {boolean}
@@ -504,7 +508,7 @@ deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
rotateSource:
@@ -2168,7 +2324,7 @@ setSource:
@@ -2381,7 +2537,7 @@ svgSource:
@@ -2537,7 +2693,7 @@ toPointsSource:
@@ -2641,7 +2797,7 @@ toSegments<
Source:
@@ -2746,7 +2902,7 @@ transformSource:
@@ -2871,7 +3027,7 @@ Returns:
diff --git a/docs/Circle.html b/docs/Circle.html
index 64ef53ed..6a43af9c 100644
--- a/docs/Circle.html
+++ b/docs/Circle.html
@@ -24,7 +24,7 @@
@@ -1788,7 +1788,7 @@ Returns:
diff --git a/docs/CircularLinkedList.html b/docs/CircularLinkedList.html
index 4e6d02cb..d3ffeaa9 100644
--- a/docs/CircularLinkedList.html
+++ b/docs/CircularLinkedList.html
@@ -24,7 +24,7 @@
@@ -664,7 +664,7 @@ Returns:
diff --git a/docs/DE9IM.html b/docs/DE9IM.html
index 529aa9f5..dc20a311 100644
--- a/docs/DE9IM.html
+++ b/docs/DE9IM.html
@@ -24,7 +24,7 @@
@@ -1507,7 +1507,7 @@ Returns:
diff --git a/docs/Edge.html b/docs/Edge.html
index ec2a6815..7918238a 100644
--- a/docs/Edge.html
+++ b/docs/Edge.html
@@ -24,7 +24,7 @@
@@ -1819,7 +1819,7 @@ Parameters:
diff --git a/docs/Errors.html b/docs/Errors.html
index 90108bd5..c6bde709 100644
--- a/docs/Errors.html
+++ b/docs/Errors.html
@@ -24,7 +24,7 @@
@@ -426,7 +426,7 @@ (static)
diff --git a/docs/Face.html b/docs/Face.html
index 3aafa87b..bb2a1342 100644
--- a/docs/Face.html
+++ b/docs/Face.html
@@ -24,7 +24,7 @@
@@ -2343,7 +2343,7 @@ Returns:
diff --git a/docs/Inversion.html b/docs/Inversion.html
index 5236a32c..216d2b83 100644
--- a/docs/Inversion.html
+++ b/docs/Inversion.html
@@ -24,7 +24,7 @@
@@ -232,7 +232,7 @@ Classes
diff --git a/docs/Line.html b/docs/Line.html
index bc683c5b..24726c29 100644
--- a/docs/Line.html
+++ b/docs/Line.html
@@ -24,7 +24,7 @@
@@ -2629,7 +2629,7 @@ Returns:
diff --git a/docs/LinkedList.html b/docs/LinkedList.html
index 1b3935d8..3d7e479f 100644
--- a/docs/LinkedList.html
+++ b/docs/LinkedList.html
@@ -24,7 +24,7 @@
@@ -1094,7 +1094,7 @@ Returns:
diff --git a/docs/Matrix.html b/docs/Matrix.html
index de61c7d6..7ee25849 100644
--- a/docs/Matrix.html
+++ b/docs/Matrix.html
@@ -24,7 +24,7 @@
@@ -1613,7 +1613,7 @@ Returns:
diff --git a/docs/Multiline.html b/docs/Multiline.html
index 98308f18..aec92f0f 100644
--- a/docs/Multiline.html
+++ b/docs/Multiline.html
@@ -24,7 +24,7 @@
@@ -1849,7 +1849,7 @@ Returns:
diff --git a/docs/PlanarSet.html b/docs/PlanarSet.html
index d57361fa..50db8074 100644
--- a/docs/PlanarSet.html
+++ b/docs/PlanarSet.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ Methods
- add(shape) → {PlanarSet}
+ add(entry) → {PlanarSet}
@@ -265,7 +265,7 @@ addSource:
@@ -309,13 +309,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
shape to be added, should have valid box property
+Another option to transfer as an object {key: Box, value: AnyShape}
@@ -421,7 +425,7 @@ clearSource:
@@ -461,7 +465,7 @@ cleardelete(shape) → {boolean}
+ delete(entry) → {boolean}
@@ -504,7 +508,7 @@ deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
svgSource:
@@ -2537,7 +2693,7 @@ toPointsSource:
@@ -2641,7 +2797,7 @@ toSegments<
Source:
@@ -2746,7 +2902,7 @@ transformSource:
@@ -2871,7 +3027,7 @@ Returns:
diff --git a/docs/Circle.html b/docs/Circle.html
index 64ef53ed..6a43af9c 100644
--- a/docs/Circle.html
+++ b/docs/Circle.html
@@ -24,7 +24,7 @@
@@ -1788,7 +1788,7 @@ Returns:
diff --git a/docs/CircularLinkedList.html b/docs/CircularLinkedList.html
index 4e6d02cb..d3ffeaa9 100644
--- a/docs/CircularLinkedList.html
+++ b/docs/CircularLinkedList.html
@@ -24,7 +24,7 @@
@@ -664,7 +664,7 @@ Returns:
diff --git a/docs/DE9IM.html b/docs/DE9IM.html
index 529aa9f5..dc20a311 100644
--- a/docs/DE9IM.html
+++ b/docs/DE9IM.html
@@ -24,7 +24,7 @@
@@ -1507,7 +1507,7 @@ Returns:
diff --git a/docs/Edge.html b/docs/Edge.html
index ec2a6815..7918238a 100644
--- a/docs/Edge.html
+++ b/docs/Edge.html
@@ -24,7 +24,7 @@
@@ -1819,7 +1819,7 @@ Parameters:
diff --git a/docs/Errors.html b/docs/Errors.html
index 90108bd5..c6bde709 100644
--- a/docs/Errors.html
+++ b/docs/Errors.html
@@ -24,7 +24,7 @@
@@ -426,7 +426,7 @@ (static)
diff --git a/docs/Face.html b/docs/Face.html
index 3aafa87b..bb2a1342 100644
--- a/docs/Face.html
+++ b/docs/Face.html
@@ -24,7 +24,7 @@
@@ -2343,7 +2343,7 @@ Returns:
diff --git a/docs/Inversion.html b/docs/Inversion.html
index 5236a32c..216d2b83 100644
--- a/docs/Inversion.html
+++ b/docs/Inversion.html
@@ -24,7 +24,7 @@
@@ -232,7 +232,7 @@ Classes
diff --git a/docs/Line.html b/docs/Line.html
index bc683c5b..24726c29 100644
--- a/docs/Line.html
+++ b/docs/Line.html
@@ -24,7 +24,7 @@
@@ -2629,7 +2629,7 @@ Returns:
diff --git a/docs/LinkedList.html b/docs/LinkedList.html
index 1b3935d8..3d7e479f 100644
--- a/docs/LinkedList.html
+++ b/docs/LinkedList.html
@@ -24,7 +24,7 @@
@@ -1094,7 +1094,7 @@ Returns:
diff --git a/docs/Matrix.html b/docs/Matrix.html
index de61c7d6..7ee25849 100644
--- a/docs/Matrix.html
+++ b/docs/Matrix.html
@@ -24,7 +24,7 @@
@@ -1613,7 +1613,7 @@ Returns:
diff --git a/docs/Multiline.html b/docs/Multiline.html
index 98308f18..aec92f0f 100644
--- a/docs/Multiline.html
+++ b/docs/Multiline.html
@@ -24,7 +24,7 @@
@@ -1849,7 +1849,7 @@ Returns:
diff --git a/docs/PlanarSet.html b/docs/PlanarSet.html
index d57361fa..50db8074 100644
--- a/docs/PlanarSet.html
+++ b/docs/PlanarSet.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ Methods
- add(shape) → {PlanarSet}
+ add(entry) → {PlanarSet}
@@ -265,7 +265,7 @@ addSource:
@@ -309,13 +309,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
shape to be added, should have valid box property
+Another option to transfer as an object {key: Box, value: AnyShape}
@@ -421,7 +425,7 @@ clearSource:
@@ -461,7 +465,7 @@ cleardelete(shape) → {boolean}
+ delete(entry) → {boolean}
@@ -504,7 +508,7 @@ deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
toSegments<
Source:
@@ -2746,7 +2902,7 @@ transformSource:
@@ -2871,7 +3027,7 @@ Returns:
diff --git a/docs/Circle.html b/docs/Circle.html
index 64ef53ed..6a43af9c 100644
--- a/docs/Circle.html
+++ b/docs/Circle.html
@@ -24,7 +24,7 @@
@@ -1788,7 +1788,7 @@ Returns:
diff --git a/docs/CircularLinkedList.html b/docs/CircularLinkedList.html
index 4e6d02cb..d3ffeaa9 100644
--- a/docs/CircularLinkedList.html
+++ b/docs/CircularLinkedList.html
@@ -24,7 +24,7 @@
@@ -664,7 +664,7 @@ Returns:
diff --git a/docs/DE9IM.html b/docs/DE9IM.html
index 529aa9f5..dc20a311 100644
--- a/docs/DE9IM.html
+++ b/docs/DE9IM.html
@@ -24,7 +24,7 @@
@@ -1507,7 +1507,7 @@ Returns:
diff --git a/docs/Edge.html b/docs/Edge.html
index ec2a6815..7918238a 100644
--- a/docs/Edge.html
+++ b/docs/Edge.html
@@ -24,7 +24,7 @@
@@ -1819,7 +1819,7 @@ Parameters:
diff --git a/docs/Errors.html b/docs/Errors.html
index 90108bd5..c6bde709 100644
--- a/docs/Errors.html
+++ b/docs/Errors.html
@@ -24,7 +24,7 @@
@@ -426,7 +426,7 @@ (static)
diff --git a/docs/Face.html b/docs/Face.html
index 3aafa87b..bb2a1342 100644
--- a/docs/Face.html
+++ b/docs/Face.html
@@ -24,7 +24,7 @@
@@ -2343,7 +2343,7 @@ Returns:
diff --git a/docs/Inversion.html b/docs/Inversion.html
index 5236a32c..216d2b83 100644
--- a/docs/Inversion.html
+++ b/docs/Inversion.html
@@ -24,7 +24,7 @@
@@ -232,7 +232,7 @@ Classes
diff --git a/docs/Line.html b/docs/Line.html
index bc683c5b..24726c29 100644
--- a/docs/Line.html
+++ b/docs/Line.html
@@ -24,7 +24,7 @@
@@ -2629,7 +2629,7 @@ Returns:
diff --git a/docs/LinkedList.html b/docs/LinkedList.html
index 1b3935d8..3d7e479f 100644
--- a/docs/LinkedList.html
+++ b/docs/LinkedList.html
@@ -24,7 +24,7 @@
@@ -1094,7 +1094,7 @@ Returns:
diff --git a/docs/Matrix.html b/docs/Matrix.html
index de61c7d6..7ee25849 100644
--- a/docs/Matrix.html
+++ b/docs/Matrix.html
@@ -24,7 +24,7 @@
@@ -1613,7 +1613,7 @@ Returns:
diff --git a/docs/Multiline.html b/docs/Multiline.html
index 98308f18..aec92f0f 100644
--- a/docs/Multiline.html
+++ b/docs/Multiline.html
@@ -24,7 +24,7 @@
@@ -1849,7 +1849,7 @@ Returns:
diff --git a/docs/PlanarSet.html b/docs/PlanarSet.html
index d57361fa..50db8074 100644
--- a/docs/PlanarSet.html
+++ b/docs/PlanarSet.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ Methods
- add(shape) → {PlanarSet}
+ add(entry) → {PlanarSet}
@@ -265,7 +265,7 @@ addSource:
@@ -309,13 +309,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
shape to be added, should have valid box property
+Another option to transfer as an object {key: Box, value: AnyShape}
@@ -421,7 +425,7 @@ clearSource:
@@ -461,7 +465,7 @@ cleardelete(shape) → {boolean}
+ delete(entry) → {boolean}
@@ -504,7 +508,7 @@ deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
Returns:
diff --git a/docs/Circle.html b/docs/Circle.html index 64ef53ed..6a43af9c 100644 --- a/docs/Circle.html +++ b/docs/Circle.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/CircularLinkedList.html b/docs/CircularLinkedList.html index 4e6d02cb..d3ffeaa9 100644 --- a/docs/CircularLinkedList.html +++ b/docs/CircularLinkedList.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/DE9IM.html b/docs/DE9IM.html index 529aa9f5..dc20a311 100644 --- a/docs/DE9IM.html +++ b/docs/DE9IM.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/Edge.html b/docs/Edge.html index ec2a6815..7918238a 100644 --- a/docs/Edge.html +++ b/docs/Edge.html @@ -24,7 +24,7 @@
Parameters:
diff --git a/docs/Errors.html b/docs/Errors.html index 90108bd5..c6bde709 100644 --- a/docs/Errors.html +++ b/docs/Errors.html @@ -24,7 +24,7 @@
(static)
diff --git a/docs/Face.html b/docs/Face.html
index 3aafa87b..bb2a1342 100644
--- a/docs/Face.html
+++ b/docs/Face.html
@@ -24,7 +24,7 @@
@@ -2343,7 +2343,7 @@ Returns:
diff --git a/docs/Inversion.html b/docs/Inversion.html
index 5236a32c..216d2b83 100644
--- a/docs/Inversion.html
+++ b/docs/Inversion.html
@@ -24,7 +24,7 @@
@@ -232,7 +232,7 @@ Classes
diff --git a/docs/Line.html b/docs/Line.html
index bc683c5b..24726c29 100644
--- a/docs/Line.html
+++ b/docs/Line.html
@@ -24,7 +24,7 @@
@@ -2629,7 +2629,7 @@ Returns:
diff --git a/docs/LinkedList.html b/docs/LinkedList.html
index 1b3935d8..3d7e479f 100644
--- a/docs/LinkedList.html
+++ b/docs/LinkedList.html
@@ -24,7 +24,7 @@
@@ -1094,7 +1094,7 @@ Returns:
diff --git a/docs/Matrix.html b/docs/Matrix.html
index de61c7d6..7ee25849 100644
--- a/docs/Matrix.html
+++ b/docs/Matrix.html
@@ -24,7 +24,7 @@
@@ -1613,7 +1613,7 @@ Returns:
diff --git a/docs/Multiline.html b/docs/Multiline.html
index 98308f18..aec92f0f 100644
--- a/docs/Multiline.html
+++ b/docs/Multiline.html
@@ -24,7 +24,7 @@
@@ -1849,7 +1849,7 @@ Returns:
diff --git a/docs/PlanarSet.html b/docs/PlanarSet.html
index d57361fa..50db8074 100644
--- a/docs/PlanarSet.html
+++ b/docs/PlanarSet.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ Methods
- add(shape) → {PlanarSet}
+ add(entry) → {PlanarSet}
@@ -265,7 +265,7 @@ addSource:
@@ -309,13 +309,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
shape to be added, should have valid box property
+Another option to transfer as an object {key: Box, value: AnyShape}
@@ -421,7 +425,7 @@ clearSource:
@@ -461,7 +465,7 @@ cleardelete(shape) → {boolean}
+ delete(entry) → {boolean}
@@ -504,7 +508,7 @@ deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
Returns:
diff --git a/docs/Inversion.html b/docs/Inversion.html index 5236a32c..216d2b83 100644 --- a/docs/Inversion.html +++ b/docs/Inversion.html @@ -24,7 +24,7 @@
Classes
diff --git a/docs/Line.html b/docs/Line.html index bc683c5b..24726c29 100644 --- a/docs/Line.html +++ b/docs/Line.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/LinkedList.html b/docs/LinkedList.html index 1b3935d8..3d7e479f 100644 --- a/docs/LinkedList.html +++ b/docs/LinkedList.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/Matrix.html b/docs/Matrix.html index de61c7d6..7ee25849 100644 --- a/docs/Matrix.html +++ b/docs/Matrix.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/Multiline.html b/docs/Multiline.html index 98308f18..aec92f0f 100644 --- a/docs/Multiline.html +++ b/docs/Multiline.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/PlanarSet.html b/docs/PlanarSet.html index d57361fa..50db8074 100644 --- a/docs/PlanarSet.html +++ b/docs/PlanarSet.html @@ -24,7 +24,7 @@
Methods
-add(shape) → {PlanarSet}
+add(entry) → {PlanarSet}
@@ -265,7 +265,7 @@addSource:
@@ -309,13 +309,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
shape to be added, should have valid box property
+Another option to transfer as an object {key: Box, value: AnyShape}
@@ -421,7 +425,7 @@ clearSource:
@@ -461,7 +465,7 @@ cleardelete(shape) → {boolean}
+ delete(entry) → {boolean}
@@ -504,7 +508,7 @@ deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
shape
entry
Shape
+AnyShape
+|
+
+Object
@@ -327,6 +330,7 @@ Parameters:
cleardelete(shape) → {boolean}
+delete(entry) → {boolean}
@@ -504,7 +508,7 @@deleteSource:
@@ -548,13 +552,16 @@ Parameters:
- shape
+ entry
-Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
- hit(point) → {Array}
+ hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@ hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
@@ -1580,7 +1580,7 @@ svgSource:
@@ -1861,7 +1861,7 @@ Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html
index 3f500ec1..ba934081 100644
--- a/docs/Polygon.html
+++ b/docs/Polygon.html
@@ -24,7 +24,7 @@
@@ -4262,7 +4262,7 @@ Returns:
diff --git a/docs/Ray.html b/docs/Ray.html
index de575291..ce332fd5 100644
--- a/docs/Ray.html
+++ b/docs/Ray.html
@@ -24,7 +24,7 @@
@@ -1633,7 +1633,7 @@ Returns:
diff --git a/docs/Segment.html b/docs/Segment.html
index 1d0935bc..221eb700 100644
--- a/docs/Segment.html
+++ b/docs/Segment.html
@@ -24,7 +24,7 @@
@@ -2854,7 +2854,7 @@ Returns:
diff --git a/docs/Shape.html b/docs/Shape.html
index c3072b9e..83a9934a 100644
--- a/docs/Shape.html
+++ b/docs/Shape.html
@@ -24,7 +24,7 @@
@@ -838,7 +838,7 @@ Returns:
diff --git a/docs/Vector.html b/docs/Vector.html
index be14d50d..65000b7a 100644
--- a/docs/Vector.html
+++ b/docs/Vector.html
@@ -24,7 +24,7 @@
@@ -2628,7 +2628,7 @@ Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html
index c3fa593a..5f2cf51f 100644
--- a/docs/algorithms_boolean_op.js.html
+++ b/docs/algorithms_boolean_op.js.html
@@ -24,7 +24,7 @@
@@ -741,7 +741,7 @@ algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html
index 46197f22..d61b05b0 100644
--- a/docs/algorithms_distance.js.html
+++ b/docs/algorithms_distance.js.html
@@ -24,7 +24,7 @@
@@ -651,7 +651,7 @@ algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html
index df4796cf..61e578dc 100644
--- a/docs/algorithms_ray_shooting.js.html
+++ b/docs/algorithms_ray_shooting.js.html
@@ -24,7 +24,7 @@
@@ -194,7 +194,7 @@ algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html
index 84ac9b9a..41856b75 100644
--- a/docs/algorithms_relation.js.html
+++ b/docs/algorithms_relation.js.html
@@ -24,7 +24,7 @@
@@ -387,7 +387,7 @@ algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html
index 65bc1826..03bb7c96 100644
--- a/docs/classes_arc.js.html
+++ b/docs/classes_arc.js.html
@@ -24,7 +24,7 @@
@@ -549,7 +549,7 @@ classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html
index af16868b..477a6d75 100644
--- a/docs/classes_box.js.html
+++ b/docs/classes_box.js.html
@@ -24,7 +24,7 @@
@@ -48,6 +48,7 @@ classes/box.js
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -285,6 +286,46 @@ classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
@@ -322,7 +363,7 @@ classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html
index bac406ad..55d4975b 100644
--- a/docs/classes_circle.js.html
+++ b/docs/classes_circle.js.html
@@ -24,7 +24,7 @@
@@ -301,7 +301,7 @@ classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html
index 80789162..447d6341 100644
--- a/docs/classes_edge.js.html
+++ b/docs/classes_edge.js.html
@@ -24,7 +24,7 @@
@@ -286,7 +286,7 @@ classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html
index 5870b0d1..b42bed7c 100644
--- a/docs/classes_face.js.html
+++ b/docs/classes_face.js.html
@@ -24,7 +24,7 @@
@@ -548,7 +548,7 @@ classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html
index 7fd0b7b1..f46dd6ab 100644
--- a/docs/classes_inversion.js.html
+++ b/docs/classes_inversion.js.html
@@ -24,7 +24,7 @@
@@ -141,7 +141,7 @@ classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html
index 9e6ed1e7..97331f96 100644
--- a/docs/classes_line.js.html
+++ b/docs/classes_line.js.html
@@ -24,7 +24,7 @@
@@ -425,7 +425,7 @@ classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html
index cabc6745..bb53e6b2 100644
--- a/docs/classes_matrix.js.html
+++ b/docs/classes_matrix.js.html
@@ -24,7 +24,7 @@
@@ -202,7 +202,7 @@ classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html
index 5dce317a..19486550 100644
--- a/docs/classes_multiline.js.html
+++ b/docs/classes_multiline.js.html
@@ -24,7 +24,7 @@
@@ -258,7 +258,7 @@ classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html
index 9a016daa..48602f21 100644
--- a/docs/classes_point.js.html
+++ b/docs/classes_point.js.html
@@ -24,7 +24,7 @@
@@ -226,7 +226,7 @@ classes/point.js
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -234,6 +234,10 @@ classes/point.js
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
@@ -304,7 +308,7 @@ classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html
index fb37a2ea..423a9c65 100644
--- a/docs/classes_polygon.js.html
+++ b/docs/classes_polygon.js.html
@@ -24,7 +24,7 @@
@@ -762,7 +762,7 @@ classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html
index d5316d40..21d8f253 100644
--- a/docs/classes_ray.js.html
+++ b/docs/classes_ray.js.html
@@ -24,7 +24,7 @@
@@ -271,7 +271,7 @@ classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html
index b9383604..9e251cb4 100644
--- a/docs/classes_segment.js.html
+++ b/docs/classes_segment.js.html
@@ -24,7 +24,7 @@
@@ -420,7 +420,7 @@ classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html
index 69dc012e..c633850e 100644
--- a/docs/classes_shape.js.html
+++ b/docs/classes_shape.js.html
@@ -24,7 +24,7 @@
@@ -122,7 +122,7 @@ classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html
index cc728206..6f7e7b0d 100644
--- a/docs/classes_vector.js.html
+++ b/docs/classes_vector.js.html
@@ -24,7 +24,7 @@
@@ -311,7 +311,7 @@ classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html
index 90ab1932..2628ea31 100644
--- a/docs/data_structures_circular_linked_list.js.html
+++ b/docs/data_structures_circular_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -117,7 +117,7 @@ data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html
index 7f8aaaba..8b717c8f 100644
--- a/docs/data_structures_de9im.js.html
+++ b/docs/data_structures_de9im.js.html
@@ -24,7 +24,7 @@
@@ -262,7 +262,7 @@ data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html
index b5073e77..c0d1d212 100644
--- a/docs/data_structures_linked_list.js.html
+++ b/docs/data_structures_linked_list.js.html
@@ -24,7 +24,7 @@
@@ -215,7 +215,7 @@ data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html
index e93292e4..307fba15 100644
--- a/docs/data_structures_planar_set.js.html
+++ b/docs/data_structures_planar_set.js.html
@@ -24,7 +24,7 @@
@@ -71,28 +71,35 @@ data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if
* a shape was actually added.<br/>
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid <i>box</i> property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -109,7 +116,7 @@ data_structures/planar_set.js
* 2d range search in planar set.<br/>
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -119,7 +126,7 @@ data_structures/planar_set.js
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
@@ -149,7 +156,7 @@ data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html
index 58382d98..1d7c411b 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
@@ -218,7 +218,7 @@ (constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
shape
entry
Shape
+AnyShape
+|
+
+Object
@@ -617,7 +624,7 @@ Returns:
-hit(point) → {Array}
+hit(point) → {Array.<AnyShape>}
@@ -660,7 +667,7 @@hitSource:
@@ -754,7 +761,7 @@ Returns:
-Array
+Array.<AnyShape>
@@ -773,7 +780,7 @@ Returns:
- search(box) → {Array.<Shapes>}
+ search(box) → {Array.<AnyShape>}
@@ -817,7 +824,7 @@ searchSource:
@@ -911,7 +918,7 @@ Returns:
-Array.<Shapes>
+Array.<AnyShape>
@@ -973,7 +980,7 @@ svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
Array
+Array.<AnyShape>
Returns:
Array.<Shapes>
+Array.<AnyShape>
svgSource:
@@ -1046,7 +1053,7 @@ Returns:
diff --git a/docs/Point.html b/docs/Point.html
index c5e5bcdb..e5ee07d6 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -24,7 +24,7 @@
@@ -1321,7 +1321,7 @@ Parameters:
- Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+
Parameters:
Returns:
diff --git a/docs/Polygon.html b/docs/Polygon.html index 3f500ec1..ba934081 100644 --- a/docs/Polygon.html +++ b/docs/Polygon.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/Ray.html b/docs/Ray.html index de575291..ce332fd5 100644 --- a/docs/Ray.html +++ b/docs/Ray.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/Segment.html b/docs/Segment.html index 1d0935bc..221eb700 100644 --- a/docs/Segment.html +++ b/docs/Segment.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/Shape.html b/docs/Shape.html index c3072b9e..83a9934a 100644 --- a/docs/Shape.html +++ b/docs/Shape.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/Vector.html b/docs/Vector.html index be14d50d..65000b7a 100644 --- a/docs/Vector.html +++ b/docs/Vector.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/algorithms_boolean_op.js.html b/docs/algorithms_boolean_op.js.html index c3fa593a..5f2cf51f 100644 --- a/docs/algorithms_boolean_op.js.html +++ b/docs/algorithms_boolean_op.js.html @@ -24,7 +24,7 @@
algorithms/boolean_op.js
diff --git a/docs/algorithms_distance.js.html b/docs/algorithms_distance.js.html index 46197f22..d61b05b0 100644 --- a/docs/algorithms_distance.js.html +++ b/docs/algorithms_distance.js.html @@ -24,7 +24,7 @@
algorithms/distance.js
diff --git a/docs/algorithms_ray_shooting.js.html b/docs/algorithms_ray_shooting.js.html index df4796cf..61e578dc 100644 --- a/docs/algorithms_ray_shooting.js.html +++ b/docs/algorithms_ray_shooting.js.html @@ -24,7 +24,7 @@
algorithms/ray_shooting.js
diff --git a/docs/algorithms_relation.js.html b/docs/algorithms_relation.js.html index 84ac9b9a..41856b75 100644 --- a/docs/algorithms_relation.js.html +++ b/docs/algorithms_relation.js.html @@ -24,7 +24,7 @@
algorithms/relation.js
diff --git a/docs/classes_arc.js.html b/docs/classes_arc.js.html index 65bc1826..03bb7c96 100644 --- a/docs/classes_arc.js.html +++ b/docs/classes_arc.js.html @@ -24,7 +24,7 @@
classes/arc.js
diff --git a/docs/classes_box.js.html b/docs/classes_box.js.html index af16868b..477a6d75 100644 --- a/docs/classes_box.js.html +++ b/docs/classes_box.js.html @@ -24,7 +24,7 @@
classes/box.js
import {convertToString} from "../utils/attributes"; import {Shape} from "./shape"; import {Errors} from "../utils/errors"; +import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection"; /** * Class Box represents bounding box of the shape. @@ -285,6 +286,46 @@classes/box.js
(new_box, pt) => new_box.merge(pt.box), new Box()) } + /** + * Return true if box contains shape: no point of shape lies outside the box + * @param {AnyShape} shape - test shape + * @returns {boolean} + */ + contains(shape) { + if (shape instanceof Flatten.Point) { + return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax); + } + + if (shape instanceof Flatten.Segment) { + return shape.vertices.every(vertex => this.contains(vertex)) + } + + if (shape instanceof Flatten.Box) { + return shape.toSegments().every(segment => this.contains(segment)) + } + + if (shape instanceof Flatten.Circle) { + return this.contains(shape.box) + } + + if (shape instanceof Flatten.Arc) { + return shape.vertices.every(vertex => this.contains(vertex)) && + shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0) + } + + if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) { + return false + } + + if (shape instanceof Flatten.Multiline) { + return shape.toShapes().every(shape => this.contains(shape)) + } + + if (shape instanceof Flatten.Polygon) { + return this.contains(shape.box) + } + } + get name() { return "box" } @@ -322,7 +363,7 @@classes/box.js
diff --git a/docs/classes_circle.js.html b/docs/classes_circle.js.html index bac406ad..55d4975b 100644 --- a/docs/classes_circle.js.html +++ b/docs/classes_circle.js.html @@ -24,7 +24,7 @@
classes/circle.js
diff --git a/docs/classes_edge.js.html b/docs/classes_edge.js.html index 80789162..447d6341 100644 --- a/docs/classes_edge.js.html +++ b/docs/classes_edge.js.html @@ -24,7 +24,7 @@
classes/edge.js
diff --git a/docs/classes_face.js.html b/docs/classes_face.js.html index 5870b0d1..b42bed7c 100644 --- a/docs/classes_face.js.html +++ b/docs/classes_face.js.html @@ -24,7 +24,7 @@
classes/face.js
diff --git a/docs/classes_inversion.js.html b/docs/classes_inversion.js.html index 7fd0b7b1..f46dd6ab 100644 --- a/docs/classes_inversion.js.html +++ b/docs/classes_inversion.js.html @@ -24,7 +24,7 @@
classes/inversion.js
diff --git a/docs/classes_line.js.html b/docs/classes_line.js.html index 9e6ed1e7..97331f96 100644 --- a/docs/classes_line.js.html +++ b/docs/classes_line.js.html @@ -24,7 +24,7 @@
classes/line.js
diff --git a/docs/classes_matrix.js.html b/docs/classes_matrix.js.html index cabc6745..bb53e6b2 100644 --- a/docs/classes_matrix.js.html +++ b/docs/classes_matrix.js.html @@ -24,7 +24,7 @@
classes/matrix.js
diff --git a/docs/classes_multiline.js.html b/docs/classes_multiline.js.html index 5dce317a..19486550 100644 --- a/docs/classes_multiline.js.html +++ b/docs/classes_multiline.js.html @@ -24,7 +24,7 @@
classes/multiline.js
diff --git a/docs/classes_point.js.html b/docs/classes_point.js.html index 9a016daa..48602f21 100644 --- a/docs/classes_point.js.html +++ b/docs/classes_point.js.html @@ -24,7 +24,7 @@
classes/point.js
/** * Returns true if point is on a shape, false otherwise - * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon + * @param {Shape} shape * @returns {boolean} */ on(shape) { @@ -234,6 +234,10 @@classes/point.js
return this.equalTo(shape); } + if (shape instanceof Flatten.Box) { + return shape.contains(this); + } + if (shape instanceof Flatten.Line) { return shape.contains(this); } @@ -304,7 +308,7 @@classes/point.js
diff --git a/docs/classes_polygon.js.html b/docs/classes_polygon.js.html index fb37a2ea..423a9c65 100644 --- a/docs/classes_polygon.js.html +++ b/docs/classes_polygon.js.html @@ -24,7 +24,7 @@
classes/polygon.js
diff --git a/docs/classes_ray.js.html b/docs/classes_ray.js.html index d5316d40..21d8f253 100644 --- a/docs/classes_ray.js.html +++ b/docs/classes_ray.js.html @@ -24,7 +24,7 @@
classes/ray.js
diff --git a/docs/classes_segment.js.html b/docs/classes_segment.js.html index b9383604..9e251cb4 100644 --- a/docs/classes_segment.js.html +++ b/docs/classes_segment.js.html @@ -24,7 +24,7 @@
classes/segment.js
diff --git a/docs/classes_shape.js.html b/docs/classes_shape.js.html index 69dc012e..c633850e 100644 --- a/docs/classes_shape.js.html +++ b/docs/classes_shape.js.html @@ -24,7 +24,7 @@
classes/shape.js
diff --git a/docs/classes_vector.js.html b/docs/classes_vector.js.html index cc728206..6f7e7b0d 100644 --- a/docs/classes_vector.js.html +++ b/docs/classes_vector.js.html @@ -24,7 +24,7 @@
classes/vector.js
diff --git a/docs/data_structures_circular_linked_list.js.html b/docs/data_structures_circular_linked_list.js.html index 90ab1932..2628ea31 100644 --- a/docs/data_structures_circular_linked_list.js.html +++ b/docs/data_structures_circular_linked_list.js.html @@ -24,7 +24,7 @@
data_structures/circular_linked_list.js
diff --git a/docs/data_structures_de9im.js.html b/docs/data_structures_de9im.js.html index 7f8aaaba..8b717c8f 100644 --- a/docs/data_structures_de9im.js.html +++ b/docs/data_structures_de9im.js.html @@ -24,7 +24,7 @@
data_structures/de9im.js
diff --git a/docs/data_structures_linked_list.js.html b/docs/data_structures_linked_list.js.html index b5073e77..c0d1d212 100644 --- a/docs/data_structures_linked_list.js.html +++ b/docs/data_structures_linked_list.js.html @@ -24,7 +24,7 @@
data_structures/linked_list.js
diff --git a/docs/data_structures_planar_set.js.html b/docs/data_structures_planar_set.js.html index e93292e4..307fba15 100644 --- a/docs/data_structures_planar_set.js.html +++ b/docs/data_structures_planar_set.js.html @@ -24,7 +24,7 @@
data_structures/planar_set.js
* This happens with no error, it is possible to use <i>size</i> property to check if * a shape was actually added.<br/> * Method returns planar set object updated and may be chained - * @param {Shape} shape - shape to be added, should have valid <i>box</i> property + * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid <i>box</i> property + * Another option to transfer as an object {key: Box, value: AnyShape} * @returns {PlanarSet} */ - add(shape) { + add(entry) { let size = this.size; + const {key, value} = entry + const box = key || entry.box + const shape = value || entry super.add(shape); // size not changed - item not added, probably trying to add same item twice if (this.size > size) { - let node = this.index.insert(shape.box, shape); + let node = this.index.insert(box, shape); } return this; // in accordance to Set.add interface } /** * Delete shape from planar set. Returns true if shape was actually deleted, false otherwise - * @param {Shape} shape - shape to be deleted + * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted * @returns {boolean} */ - delete(shape) { + delete(entry) { + const {key, value} = entry + const box = key || entry.box + const shape = value || entry let deleted = super.delete(shape); if (deleted) { - this.index.remove(shape.box, shape); + this.index.remove(box, shape); } return deleted; } @@ -109,7 +116,7 @@data_structures/planar_set.js
* 2d range search in planar set.<br/> * Returns array of all shapes in planar set which bounding box is intersected with query box * @param {Box} box - query box - * @returns {Shapes[]} + * @returns {AnyShape[]} */ search(box) { let resp = this.index.search(box); @@ -119,7 +126,7 @@data_structures/planar_set.js
/** * Point location test. Returns array of shapes which contains given point * @param {Point} point - query point - * @returns {Array} + * @returns {AnyShape[]} */ hit(point) { let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1); @@ -149,7 +156,7 @@data_structures/planar_set.js
diff --git a/docs/global.html b/docs/global.html index 58382d98..1d7c411b 100644 --- a/docs/global.html +++ b/docs/global.html @@ -24,7 +24,7 @@
(constant) boxSource:
@@ -900,7 +900,7 @@ (constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
(constant) point
Source:
@@ -2466,7 +2466,7 @@ Parameters:
diff --git a/docs/index.html b/docs/index.html
index 8009159f..2188a7e7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
@@ -341,7 +341,7 @@ Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html
index 962cadd8..2bf81684 100644
--- a/docs/module-BooleanOperations.html
+++ b/docs/module-BooleanOperations.html
@@ -24,7 +24,7 @@
@@ -1185,7 +1185,7 @@ Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html
index 7d228dde..9ed56370 100644
--- a/docs/module-RayShoot.html
+++ b/docs/module-RayShoot.html
@@ -24,7 +24,7 @@
@@ -275,7 +275,7 @@ Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html
index 4e406fb2..5a910e7f 100644
--- a/docs/module-Relation.html
+++ b/docs/module-Relation.html
@@ -24,7 +24,7 @@
@@ -1641,7 +1641,7 @@ Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html
index e8068140..5503d170 100644
--- a/docs/utils_constants.js.html
+++ b/docs/utils_constants.js.html
@@ -24,7 +24,7 @@
@@ -85,7 +85,7 @@ utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html
index 49fc9184..075b96da 100644
--- a/docs/utils_errors.js.html
+++ b/docs/utils_errors.js.html
@@ -24,7 +24,7 @@
@@ -108,7 +108,7 @@ utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html
index c8f31b02..10a5909a 100644
--- a/docs/utils_utils.js.html
+++ b/docs/utils_utils.js.html
@@ -24,7 +24,7 @@
@@ -135,7 +135,7 @@ utils/utils.js
diff --git a/index.d.ts b/index.d.ts
index 897f2034..e17d6862 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -183,6 +183,7 @@ declare namespace Flatten {
clone(): Box;
not_intersect(box: Box): boolean;
intersect(box: Box): boolean;
+ contains(shape: AnyShape): boolean;
merge(box: Box): Box;
less_than(box: Box): boolean;
equal_to(box: Box): boolean;
@@ -412,26 +413,22 @@ declare namespace Flatten {
translate(vector: Vector) : Matrix;
}
- // any object that has "box" property that implements "Interval" interface may be indexable
- // all shapes has box property that fits Interval interface
- interface IndexableElement {
- box: Interval;
- }
+ type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape}
// @ts-ignore (Set)
class PlanarSet extends Set {
// @ts-ignore (Set)
- constructor(shapes?: IndexableElement[] | Set);
+ constructor(shapes?: PlanarSetEntry[] | Set);
// members
index: IntervalTree;
// public methods
- add(element: IndexableElement): this;
- delete(element: IndexableElement): boolean;
+ add(element: PlanarSetEntry): this;
+ delete(element: PlanarSetEntry): boolean;
clear() : void;
- hit(pt: Point): IndexableElement[];
- search(box: Box): IndexableElement[];
+ hit(pt: Point): AnyShape[];
+ search(box: Box): AnyShape[];
svg(): string;
}
diff --git a/package.json b/package.json
index 62dc7116..01eb0534 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@flatten-js/core",
- "version": "1.4.7",
+ "version": "1.4.8",
"description": "Javascript library for 2d geometry",
"main": "dist/main.cjs",
"umd:main": "dist/main.umd.js",
diff --git a/src/classes/box.js b/src/classes/box.js
index 4bade3ee..3f12e5a5 100644
--- a/src/classes/box.js
+++ b/src/classes/box.js
@@ -7,6 +7,7 @@ import Flatten from '../flatten';
import {convertToString} from "../utils/attributes";
import {Shape} from "./shape";
import {Errors} from "../utils/errors";
+import {intersectSegment2Arc, intersectSegment2Circle} from "../algorithms/intersection";
/**
* Class Box represents bounding box of the shape.
@@ -244,6 +245,46 @@ export class Box extends Shape {
(new_box, pt) => new_box.merge(pt.box), new Box())
}
+ /**
+ * Return true if box contains shape: no point of shape lies outside the box
+ * @param {AnyShape} shape - test shape
+ * @returns {boolean}
+ */
+ contains(shape) {
+ if (shape instanceof Flatten.Point) {
+ return (shape.x >= this.xmin) && (shape.x <= this.xmax) && (shape.y >= this.ymin) && (shape.y <= this.ymax);
+ }
+
+ if (shape instanceof Flatten.Segment) {
+ return shape.vertices.every(vertex => this.contains(vertex))
+ }
+
+ if (shape instanceof Flatten.Box) {
+ return shape.toSegments().every(segment => this.contains(segment))
+ }
+
+ if (shape instanceof Flatten.Circle) {
+ return this.contains(shape.box)
+ }
+
+ if (shape instanceof Flatten.Arc) {
+ return shape.vertices.every(vertex => this.contains(vertex)) &&
+ shape.toSegments().every(segment => intersectSegment2Arc(segment, shape).length === 0)
+ }
+
+ if (shape instanceof Flatten.Line || shape instanceof Flatten.Ray) {
+ return false
+ }
+
+ if (shape instanceof Flatten.Multiline) {
+ return shape.toShapes().every(shape => this.contains(shape))
+ }
+
+ if (shape instanceof Flatten.Polygon) {
+ return this.contains(shape.box)
+ }
+ }
+
get name() {
return "box"
}
diff --git a/src/classes/point.js b/src/classes/point.js
index 3522ca13..e06672f7 100644
--- a/src/classes/point.js
+++ b/src/classes/point.js
@@ -185,7 +185,7 @@ export class Point extends Shape {
/**
* Returns true if point is on a shape, false otherwise
- * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon
+ * @param {Shape} shape
* @returns {boolean}
*/
on(shape) {
@@ -193,6 +193,10 @@ export class Point extends Shape {
return this.equalTo(shape);
}
+ if (shape instanceof Flatten.Box) {
+ return shape.contains(this);
+ }
+
if (shape instanceof Flatten.Line) {
return shape.contains(this);
}
diff --git a/src/data_structures/planar_set.js b/src/data_structures/planar_set.js
index 40e3359a..502d09c9 100644
--- a/src/data_structures/planar_set.js
+++ b/src/data_structures/planar_set.js
@@ -30,28 +30,35 @@ export class PlanarSet extends Set {
* This happens with no error, it is possible to use size property to check if
* a shape was actually added.
* Method returns planar set object updated and may be chained
- * @param {Shape} shape - shape to be added, should have valid box property
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property
+ * Another option to transfer as an object {key: Box, value: AnyShape}
* @returns {PlanarSet}
*/
- add(shape) {
+ add(entry) {
let size = this.size;
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
super.add(shape);
// size not changed - item not added, probably trying to add same item twice
if (this.size > size) {
- let node = this.index.insert(shape.box, shape);
+ let node = this.index.insert(box, shape);
}
return this; // in accordance to Set.add interface
}
/**
* Delete shape from planar set. Returns true if shape was actually deleted, false otherwise
- * @param {Shape} shape - shape to be deleted
+ * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted
* @returns {boolean}
*/
- delete(shape) {
+ delete(entry) {
+ const {key, value} = entry
+ const box = key || entry.box
+ const shape = value || entry
let deleted = super.delete(shape);
if (deleted) {
- this.index.remove(shape.box, shape);
+ this.index.remove(box, shape);
}
return deleted;
}
@@ -68,7 +75,7 @@ export class PlanarSet extends Set {
* 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box
* @param {Box} box - query box
- * @returns {Shapes[]}
+ * @returns {AnyShape[]}
*/
search(box) {
let resp = this.index.search(box);
@@ -78,7 +85,7 @@ export class PlanarSet extends Set {
/**
* Point location test. Returns array of shapes which contains given point
* @param {Point} point - query point
- * @returns {Array}
+ * @returns {AnyShape[]}
*/
hit(point) {
let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1);
diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js
index ef5f7c7b..62633df6 100644
--- a/test/data_structures/planar_set.js
+++ b/test/data_structures/planar_set.js
@@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(circle)).to.equal(true);
expect(planarSet.size).to.equal(2);
});
+ it('May add planar objects using {key, value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ expect(planarSet.has(segment)).to.equal(true);
+ expect(planarSet.has(circle)).to.equal(true);
+ expect(planarSet.size).to.equal(2);
+ });
it('May delete planar objects', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
@@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() {
expect(planarSet.has(segment)).to.equal(false);
expect(planarSet.size).to.equal(1);
});
+ it('May delete planar objects using {key,value} interface', function () {
+ let planarSet = new PlanarSet();
+ let segment = new Segment(1,2,4,5);
+ let circle = new Circle(new Point(3,3), 5);
+ planarSet.add({key: segment.box, value: segment});
+ planarSet.add({key: circle.box, value: circle});
+ planarSet.delete({key: segment.box, value: segment});
+ expect(planarSet.has(segment)).to.equal(false);
+ expect(planarSet.size).to.equal(1);
+ });
it('May not add same object twice (without error ?) ', function () {
let planarSet = new PlanarSet();
let segment = new Segment(1,2,4,5);
Support
diff --git a/docs/module-BooleanOperations.html b/docs/module-BooleanOperations.html index 962cadd8..2bf81684 100644 --- a/docs/module-BooleanOperations.html +++ b/docs/module-BooleanOperations.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/module-RayShoot.html b/docs/module-RayShoot.html index 7d228dde..9ed56370 100644 --- a/docs/module-RayShoot.html +++ b/docs/module-RayShoot.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/module-Relation.html b/docs/module-Relation.html index 4e406fb2..5a910e7f 100644 --- a/docs/module-Relation.html +++ b/docs/module-Relation.html @@ -24,7 +24,7 @@
Returns:
diff --git a/docs/utils_constants.js.html b/docs/utils_constants.js.html index e8068140..5503d170 100644 --- a/docs/utils_constants.js.html +++ b/docs/utils_constants.js.html @@ -24,7 +24,7 @@
utils/constants.js
diff --git a/docs/utils_errors.js.html b/docs/utils_errors.js.html index 49fc9184..075b96da 100644 --- a/docs/utils_errors.js.html +++ b/docs/utils_errors.js.html @@ -24,7 +24,7 @@
utils/errors.js
diff --git a/docs/utils_utils.js.html b/docs/utils_utils.js.html index c8f31b02..10a5909a 100644 --- a/docs/utils_utils.js.html +++ b/docs/utils_utils.js.html @@ -24,7 +24,7 @@
utils/utils.js
diff --git a/index.d.ts b/index.d.ts index 897f2034..e17d6862 100644 --- a/index.d.ts +++ b/index.d.ts @@ -183,6 +183,7 @@ declare namespace Flatten { clone(): Box; not_intersect(box: Box): boolean; intersect(box: Box): boolean; + contains(shape: AnyShape): boolean; merge(box: Box): Box; less_than(box: Box): boolean; equal_to(box: Box): boolean; @@ -412,26 +413,22 @@ declare namespace Flatten { translate(vector: Vector) : Matrix; } - // any object that has "box" property that implements "Interval" interface may be indexable - // all shapes has box property that fits Interval interface - interface IndexableElement { - box: Interval; - } + type PlanarSetEntry = AnyShape | {key: Box, value: AnyShape} // @ts-ignore (Set) class PlanarSet extends Set { // @ts-ignore (Set) - constructor(shapes?: IndexableElement[] | Set
* Method returns planar set object updated and may be chained - * @param {Shape} shape - shape to be added, should have valid box property + * @param {AnyShape | {Box, AnyShape}} entry - shape to be added, should have valid box property + * Another option to transfer as an object {key: Box, value: AnyShape} * @returns {PlanarSet} */ - add(shape) { + add(entry) { let size = this.size; + const {key, value} = entry + const box = key || entry.box + const shape = value || entry super.add(shape); // size not changed - item not added, probably trying to add same item twice if (this.size > size) { - let node = this.index.insert(shape.box, shape); + let node = this.index.insert(box, shape); } return this; // in accordance to Set.add interface } /** * Delete shape from planar set. Returns true if shape was actually deleted, false otherwise - * @param {Shape} shape - shape to be deleted + * @param {AnyShape | {Box, AnyShape}} entry - shape to be deleted * @returns {boolean} */ - delete(shape) { + delete(entry) { + const {key, value} = entry + const box = key || entry.box + const shape = value || entry let deleted = super.delete(shape); if (deleted) { - this.index.remove(shape.box, shape); + this.index.remove(box, shape); } return deleted; } @@ -68,7 +75,7 @@ export class PlanarSet extends Set { * 2d range search in planar set.
* Returns array of all shapes in planar set which bounding box is intersected with query box * @param {Box} box - query box - * @returns {Shapes[]} + * @returns {AnyShape[]} */ search(box) { let resp = this.index.search(box); @@ -78,7 +85,7 @@ export class PlanarSet extends Set { /** * Point location test. Returns array of shapes which contains given point * @param {Point} point - query point - * @returns {Array} + * @returns {AnyShape[]} */ hit(point) { let box = new Flatten.Box(point.x - 1, point.y - 1, point.x + 1, point.y + 1); diff --git a/test/data_structures/planar_set.js b/test/data_structures/planar_set.js index ef5f7c7b..62633df6 100644 --- a/test/data_structures/planar_set.js +++ b/test/data_structures/planar_set.js @@ -28,6 +28,16 @@ describe('#Data_structures.PlanarSet', function() { expect(planarSet.has(circle)).to.equal(true); expect(planarSet.size).to.equal(2); }); + it('May add planar objects using {key, value} interface', function () { + let planarSet = new PlanarSet(); + let segment = new Segment(1,2,4,5); + let circle = new Circle(new Point(3,3), 5); + planarSet.add({key: segment.box, value: segment}); + planarSet.add({key: circle.box, value: circle}); + expect(planarSet.has(segment)).to.equal(true); + expect(planarSet.has(circle)).to.equal(true); + expect(planarSet.size).to.equal(2); + }); it('May delete planar objects', function () { let planarSet = new PlanarSet(); let segment = new Segment(1,2,4,5); @@ -38,6 +48,16 @@ describe('#Data_structures.PlanarSet', function() { expect(planarSet.has(segment)).to.equal(false); expect(planarSet.size).to.equal(1); }); + it('May delete planar objects using {key,value} interface', function () { + let planarSet = new PlanarSet(); + let segment = new Segment(1,2,4,5); + let circle = new Circle(new Point(3,3), 5); + planarSet.add({key: segment.box, value: segment}); + planarSet.add({key: circle.box, value: circle}); + planarSet.delete({key: segment.box, value: segment}); + expect(planarSet.has(segment)).to.equal(false); + expect(planarSet.size).to.equal(1); + }); it('May not add same object twice (without error ?) ', function () { let planarSet = new PlanarSet(); let segment = new Segment(1,2,4,5);