chore: re-export GeometricUtil from `diagram-js`

This commit is contained in:
Martin Stamm 2022-05-24 14:25:46 +02:00 committed by fake-join[bot]
parent 3d193b2933
commit 6c3d50584c
2 changed files with 7 additions and 235 deletions

View File

@ -1,121 +1 @@
/**
* Returns the length of a vector
*
* @param {Vector}
* @return {Float}
*/
export function vectorLength(v) {
return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2));
}
/**
* Calculates the angle between a line a the yAxis
*
* @param {Array}
* @return {Float}
*/
export function getAngle(line) {
// return value is between 0, 180 and -180, -0
// @janstuemmel: maybe replace return a/b with b/a
return Math.atan((line[1].y - line[0].y) / (line[1].x - line[0].x));
}
/**
* Rotates a vector by a given angle
*
* @param {Vector}
* @param {Float} Angle in radians
* @return {Vector}
*/
export function rotateVector(vector, angle) {
return (!angle) ? vector : {
x: Math.cos(angle) * vector.x - Math.sin(angle) * vector.y,
y: Math.sin(angle) * vector.x + Math.cos(angle) * vector.y
};
}
/**
* Solves a 2D equation system
* a + r*b = c, where a,b,c are 2D vectors
*
* @param {Vector}
* @param {Vector}
* @param {Vector}
* @return {Float}
*/
function solveLambaSystem(a, b, c) {
// the 2d system
var system = [
{ n: a[0] - c[0], lambda: b[0] },
{ n: a[1] - c[1], lambda: b[1] }
];
// solve
var n = system[0].n * b[0] + system[1].n * b[1],
l = system[0].lambda * b[0] + system[1].lambda * b[1];
return -n/l;
}
/**
* Position of perpendicular foot
*
* @param {Point}
* @param [ {Point}, {Point} ] line defined through two points
* @return {Point} the perpendicular foot position
*/
export function perpendicularFoot(point, line) {
var a = line[0], b = line[1];
// relative position of b from a
var bd = { x: b.x - a.x, y: b.y - a.y };
// solve equation system to the parametrized vectors param real value
var r = solveLambaSystem([ a.x, a.y ], [ bd.x, bd.y ], [ point.x, point.y ]);
return { x: a.x + r*bd.x, y: a.y + r*bd.y };
}
/**
* Calculates the distance between a point and a line
*
* @param {Point}
* @param [ {Point}, {Point} ] line defined through two points
* @return {Float} distance
*/
export function getDistancePointLine(point, line) {
var pfPoint = perpendicularFoot(point, line);
// distance vector
var connectionVector = {
x: pfPoint.x - point.x,
y: pfPoint.y - point.y
};
return vectorLength(connectionVector);
}
/**
* Calculates the distance between two points
*
* @param {Point}
* @param {Point}
* @return {Float} distance
*/
export function getDistancePointPoint(point1, point2) {
return vectorLength({
x: point1.x - point2.x,
y: point1.y - point2.y
});
}
export * from 'diagram-js/lib/features/bendpoints/GeometricUtil';

View File

@ -9,122 +9,14 @@ import {
describe('modeling/behavior/util - GeometricUtil', function() {
it('should calculate right horizontal-line/point distance', function() {
it('should re-export diagram-js utility', function() {
// given
var testData = [
{ point: { x: 2, y: 4 }, line: [ { x: 1, y: 1 }, { x: 4, y: 1 } ], distance: 3 },
{ point: { x: 2, y: 2 }, line: [ { x: 1, y: 1 }, { x: 1, y: 4 } ], distance: 1 },
{ point: { x: 0, y: 0 }, line: [ { x: 0, y: 4 }, { x: 4, y: 0 } ], distance: 3 }
];
expect(getDistancePointLine).to.exist;
expect(getAngle).to.exist;
expect(getDistancePointPoint).to.exist;
expect(perpendicularFoot).to.exist;
expect(rotateVector).to.exist;
for (var i=0; i<testData.length; i++) {
// when
var d = getDistancePointLine(testData[i].point, testData[i].line);
// then
expect(Math.round(d)).to.be.equal(testData[i].distance);
}
});
it('should calculate right perpendicular foot', function() {
// given
var testData = [
{ point: { x: 2, y: 2 }, line: [ { x: 1, y: 1 }, { x: 1, y: 3 } ], foot: { x: 1, y: 2 } },
{ point: { x: 2, y: 4 }, line: [ { x: 1, y: 1 }, { x: 4, y: 1 } ], foot: { x: 2, y: 1 } }
];
for (var i=0; i<testData.length; i++) {
// when
var foot = perpendicularFoot(testData[i].point, testData[i].line);
// then
expect(rounded(foot)).to.be.eql(testData[i].foot);
}
});
it('should calculate right distance', function() {
var testData = [
{ p1: { x: 1, y: 1 }, p2: { x: 5, y: 1 }, distance: 4 },
{ p1: { x: 1, y: 1 }, p2: { x: 1, y: 5 }, distance: 4 },
{ p1: { x: 1, y: 1 }, p2: { x: 5, y: 5 }, distance: 6 },
{ p1: { x: 1, y: 1 }, p2: { x: -5, y: -5 }, distance: 8 }
];
for (var i=0; i<testData.length; i++) {
// when
var d = getDistancePointPoint(testData[i].p1, testData[i].p2);
// then
expect(Math.round(d)).to.be.eql(testData[i].distance);
}
});
it('should calculate right line angle', function() {
// given
var testLines = [
{ line: [ { x: 0, y: 0 }, { x: 10, y: 10 } ], angle: 45 },
{ line: [ { x: 0, y: 0 }, { x: 0, y: 10 } ], angle: 90 },
{ line: [ { x: 0, y: 0 }, { x: -10, y: 10 } ], angle: -45 },
{ line: [ { x: 0, y: 0 }, { x: 10, y: 0 } ], angle: 0 },
{ line: [ { x: 0, y: 0 }, { x: 0, y: -10 } ], angle: -90 },
{ line: [ { x: 0, y: 0 }, { x: -10, y: 0 } ], angle: 0 }
];
for (var i=0; i<testLines.length; i++) {
// when
var angle = getAngle(testLines[i].line);
// to degree
angle = angle * (180 / Math.PI);
// then
expect(angle).to.be.equal(testLines[i].angle);
}
});
it('should rotate vector', function() {
// given
var testVectors = [
// x=-10 because we have system with flipped y axis
{ vector: { x: 0, y: 10 }, angle: 90, rotated: { x: -10, y: 0 } },
{ vector: { x: 10, y: 0 }, angle: 90, rotated: { x: 0, y: 10 } },
{ vector: { x: 10, y: 0 }, angle: 45, rotated: { x: 7, y: 7 } }
];
for (var i=0; i<testVectors.length; i++) {
// degree to radian
var angle = testVectors[i].angle * (Math.PI / 180);
// when
var rotatedVector = rotateVector(testVectors[i].vector, angle);
// then
expect(rounded(rotatedVector)).to.be.eql(testVectors[i].rotated);
}
});
});
function rounded(v) {
return {
x: Math.round(v.x),
y: Math.round(v.y)
};
}