rails-physics 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rails-physics",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A plugin for the matter-js physics library designed to efficiently simulate objects moving in a one-dimensional space whose projection onto the 2-dimensional space of the screen changes over time",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -1,40 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
//Get the index of the
|
|
16
|
-
export function
|
|
17
|
-
if (segment.
|
|
18
|
-
//ToDo: Make this a custom error type
|
|
19
|
-
throw new Error("The children of leaf nodes should not be queried");
|
|
20
|
-
return -1;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
//
|
|
27
|
-
export function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
throw new Error("The children of leaf nodes should not be queried");
|
|
31
|
-
return -1;
|
|
32
|
-
} else {
|
|
33
|
-
return segment.right_child;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
//Return true iff this segment is unit width and should be a leaf.
|
|
38
|
-
export function isLeaf(segment: Segment) : boolean {
|
|
39
|
-
return (segment.left + 1) === segment.right;
|
|
40
|
-
}
|
|
1
|
+
export function center(segment) {
|
|
2
|
+
return segment.left + ((segment.right - segment.left) >> 1); // + ((segment.right - segment.left) & 1);
|
|
3
|
+
}
|
|
4
|
+
//Get the index of the left child of the segment passed as an argument
|
|
5
|
+
export function leftChild(segment) {
|
|
6
|
+
if (segment.left_child === undefined) {
|
|
7
|
+
//ToDo: Make this a custom error type
|
|
8
|
+
throw new Error("The children of leaf nodes should not be queried");
|
|
9
|
+
return -1;
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
return segment.left_child;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//Get the index of the right child of the segment passed as an argument
|
|
16
|
+
export function rightChild(segment) {
|
|
17
|
+
if (segment.right_child === undefined) {
|
|
18
|
+
//ToDo: Make this a custom error type
|
|
19
|
+
throw new Error("The children of leaf nodes should not be queried");
|
|
20
|
+
return -1;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return segment.right_child;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//Return true iff this segment is unit width and should be a leaf.
|
|
27
|
+
export function isLeaf(segment) {
|
|
28
|
+
return (segment.left + 1) === segment.right;
|
|
29
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _SegmentTree_raw;
|
|
13
|
+
import { center, leftChild, rightChild, isLeaf } from "./segment.js";
|
|
14
|
+
//Implement a segment tree for O(log(n)) updates and O(log(n)) location of center of mass
|
|
15
|
+
export class SegmentTree {
|
|
16
|
+
constructor(container, element_count, default_density = 0, external_width) {
|
|
17
|
+
_SegmentTree_raw.set(this, void 0);
|
|
18
|
+
this.surrounding = container;
|
|
19
|
+
this.external_width = external_width;
|
|
20
|
+
this.element_count = element_count;
|
|
21
|
+
element_count = Math.abs(Math.round(element_count));
|
|
22
|
+
__classPrivateFieldSet(this, _SegmentTree_raw, [{ mass: default_density * element_count, left: 0, right: element_count, parent: -1 }], "f");
|
|
23
|
+
let index = 0;
|
|
24
|
+
while (index < __classPrivateFieldGet(this, _SegmentTree_raw, "f").length) {
|
|
25
|
+
console.log(index, __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].left, __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].right);
|
|
26
|
+
if (!isLeaf(__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index])) {
|
|
27
|
+
let middle = center(__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index]);
|
|
28
|
+
__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].left_child = __classPrivateFieldGet(this, _SegmentTree_raw, "f").length;
|
|
29
|
+
__classPrivateFieldGet(this, _SegmentTree_raw, "f").push({ mass: default_density * (middle - __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].left), left: __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].left, right: middle, parent: index });
|
|
30
|
+
__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].right_child = __classPrivateFieldGet(this, _SegmentTree_raw, "f").length;
|
|
31
|
+
__classPrivateFieldGet(this, _SegmentTree_raw, "f").push({ mass: default_density * (__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].right - middle), left: middle, right: __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].right, parent: index });
|
|
32
|
+
}
|
|
33
|
+
index++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
centerOfMass() {
|
|
37
|
+
let target = __classPrivateFieldGet(this, _SegmentTree_raw, "f")[0].mass / 2;
|
|
38
|
+
let index = 0;
|
|
39
|
+
while (!isLeaf(__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index])) {
|
|
40
|
+
console.log(target, index, leftChild(__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index]), __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].mass);
|
|
41
|
+
if (__classPrivateFieldGet(this, _SegmentTree_raw, "f")[leftChild(__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index])].mass > target) {
|
|
42
|
+
index = leftChild(__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index]);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
target -= __classPrivateFieldGet(this, _SegmentTree_raw, "f")[leftChild(__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index])].mass;
|
|
46
|
+
index = rightChild(__classPrivateFieldGet(this, _SegmentTree_raw, "f")[index]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
let center = __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].left;
|
|
50
|
+
if (target > 0 && __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].mass > target) {
|
|
51
|
+
center += (1.0 * target) / __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].mass;
|
|
52
|
+
}
|
|
53
|
+
console.log(target, __classPrivateFieldGet(this, _SegmentTree_raw, "f")[index].left, center, "!");
|
|
54
|
+
return this.external_width * (center / this.element_count);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
_SegmentTree_raw = new WeakMap();
|
|
58
|
+
;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {SegmentTree} from "../ranges/segmenttree.js"
|
|
2
|
-
import Matter from "matter-js";
|
|
3
|
-
let test = new SegmentTree(Matter.Bodies.circle(20, 20, 90), 27, 1, 50.7);
|
|
4
|
-
console.log(test);
|
|
5
|
-
console.log(test.centerOfMass());
|
|
1
|
+
import { SegmentTree } from "../ranges/segmenttree.js";
|
|
2
|
+
import Matter from "matter-js";
|
|
3
|
+
let test = new SegmentTree(Matter.Bodies.circle(20, 20, 90), 27, 1, 50.7);
|
|
4
|
+
console.log(test);
|
|
5
|
+
console.log(test.centerOfMass());
|
|
File without changes
|
package/ranges/SegmentTree.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type { Segment } from "./segment.js"
|
|
2
|
-
import { center, leftChild, rightChild, isLeaf} from "./segment.js"
|
|
3
|
-
import Matter from "matter-js";
|
|
4
|
-
//Implement a segment tree for O(log(n)) updates and O(log(n)) location of center of mass
|
|
5
|
-
export class SegmentTree {
|
|
6
|
-
#raw: Segment[];
|
|
7
|
-
//external_width stores the width of the object in an external unit, such as pixels (px).
|
|
8
|
-
readonly external_width: number;
|
|
9
|
-
//Stores the number of unit sized segments used to simulate the object. NOT equal to #raw.length
|
|
10
|
-
readonly element_count: number;
|
|
11
|
-
//The "forward" axis along which the block or other massive object slides
|
|
12
|
-
slide_axis: Matter.Vector;
|
|
13
|
-
|
|
14
|
-
transverse_axis: Matter.Vector;
|
|
15
|
-
|
|
16
|
-
constructor(container: Matter.Body, element_count: number, external_width: number) {
|
|
17
|
-
this.external_width = external_width;
|
|
18
|
-
this.element_count = element_count;
|
|
19
|
-
this.slide_axis = Matter.Vector.create(0, 1);
|
|
20
|
-
this.transverse_axis = Matter.Vector.create(1, 0);
|
|
21
|
-
element_count = Math.abs(Math.round(element_count));
|
|
22
|
-
let default_density = container.density;
|
|
23
|
-
this.#raw = [{ mass: default_density * element_count, left: 0, right: element_count, parent: -1}];
|
|
24
|
-
let index = 0;
|
|
25
|
-
while(index < this.#raw.length) {
|
|
26
|
-
console.log(index, this.#raw[index].left, this.#raw[index].right);
|
|
27
|
-
if(!isLeaf(this.#raw[index])) {
|
|
28
|
-
let middle = center(this.#raw[index]);
|
|
29
|
-
this.#raw[index].left_child = this.#raw.length;
|
|
30
|
-
this.#raw.push({mass: default_density * (middle - this.#raw[index].left), left: this.#raw[index].left, right: middle, parent: index});
|
|
31
|
-
this.#raw[index].right_child = this.#raw.length;
|
|
32
|
-
this.#raw.push({mass: default_density * (this.#raw[index].right - middle), left: middle, right: this.#raw[index].right, parent: index});
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
index++;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
centerOfMass(): number {
|
|
40
|
-
let target = this.#raw[0].mass / 2;
|
|
41
|
-
let index = 0;
|
|
42
|
-
while(!isLeaf(this.#raw[index])) {
|
|
43
|
-
console.log(target, index, leftChild(this.#raw[index]), this.#raw[index].mass);
|
|
44
|
-
if(this.#raw[leftChild(this.#raw[index])].mass > target) {
|
|
45
|
-
index = leftChild(this.#raw[index]);
|
|
46
|
-
} else {
|
|
47
|
-
target -= this.#raw[leftChild(this.#raw[index])].mass;
|
|
48
|
-
index = rightChild(this.#raw[index]);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
let center = this.#raw[index].left;
|
|
52
|
-
if(target > 0 && this.#raw[index].mass > target) {
|
|
53
|
-
center += (1.0 * target) / this.#raw[index].mass;
|
|
54
|
-
}
|
|
55
|
-
console.log(target, this.#raw[index].left, center, "!");
|
|
56
|
-
return this.external_width * (center / this.element_count);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
};
|