- added a 2D collision detection for new added systems, closed #570
This commit is contained in:
@@ -40,18 +40,48 @@ define(() => {
|
||||
*/
|
||||
this._getElementDimension = (element) => {
|
||||
let dim = null;
|
||||
if(element){
|
||||
// add "gap" to a and b in order to have some space around elements
|
||||
dim = {
|
||||
left: element.style.left ? parseInt(element.style.left, 10) : 0,
|
||||
top: element.style.top ? parseInt(element.style.top, 10) : 0,
|
||||
a: parseInt((element.offsetWidth / 2).toString(), 10) + this._config.gapX,
|
||||
b: parseInt((element.offsetHeight / 2).toString(), 10) + this._config.gapY,
|
||||
width: element.offsetWidth,
|
||||
height: element.offsetHeight
|
||||
};
|
||||
|
||||
let left = 0;
|
||||
let top = 0;
|
||||
let a = 0;
|
||||
let b = 0;
|
||||
let width = this._config.newElementWidth;
|
||||
let height = this._config.newElementHeight;
|
||||
|
||||
if(Array.isArray(element)){
|
||||
// xy coordinates
|
||||
let point = [
|
||||
element[0] ? parseInt(element[0], 10) : 0,
|
||||
element[1] ? parseInt(element[1], 10) : 0
|
||||
];
|
||||
|
||||
if(this._config.grid){
|
||||
point = this._transformPointToGrid(point);
|
||||
}
|
||||
|
||||
left = point[0];
|
||||
top = point[1];
|
||||
a = this._config.gapX ;
|
||||
b = this._config.gapY ;
|
||||
}else if(element){
|
||||
// DOM element
|
||||
left = element.style.left ? parseInt(element.style.left, 10) : 0;
|
||||
top = element.style.top ? parseInt(element.style.top, 10) : 0;
|
||||
a = parseInt((element.offsetWidth / 2).toString(), 10) + this._config.gapX;
|
||||
b = parseInt((element.offsetHeight / 2).toString(), 10) + this._config.gapY;
|
||||
width = element.offsetWidth;
|
||||
height = element.offsetHeight;
|
||||
}
|
||||
return dim;
|
||||
|
||||
// add "gap" to a and b in order to have some space around elements
|
||||
return {
|
||||
left: left,
|
||||
top: top,
|
||||
a: a,
|
||||
b: b,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -96,6 +126,18 @@ define(() => {
|
||||
return dimensions;
|
||||
};
|
||||
|
||||
/**
|
||||
* transform a x/y point into a x/y point that snaps to grid
|
||||
* @param point
|
||||
* @returns {*}
|
||||
* @private
|
||||
*/
|
||||
this._transformPointToGrid = (point) => {
|
||||
point[0] = Math.floor(point[0] / this._config.grid[0]) * this._config.grid[0];
|
||||
point[1] = Math.floor(point[1] / this._config.grid[1]) * this._config.grid[1];
|
||||
return point;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform a x/y coordinate into a 2D element with width/height
|
||||
* @param centerDimension
|
||||
@@ -136,8 +178,9 @@ define(() => {
|
||||
|
||||
// transform to grid coordinates (if grid snapping is enabled) ------------------------------------
|
||||
if(this._config.grid){
|
||||
left = Math.floor(left / this._config.grid[0]) * this._config.grid[0];
|
||||
top = Math.floor(top / this._config.grid[1]) * this._config.grid[1];
|
||||
let point = this._transformPointToGrid([left, top]);
|
||||
left = point[0];
|
||||
top = point[1];
|
||||
}
|
||||
|
||||
dim = {
|
||||
@@ -239,14 +282,30 @@ define(() => {
|
||||
steps = steps || 1;
|
||||
loops = loops || 1;
|
||||
|
||||
if(loops === 1){
|
||||
// check center element
|
||||
let centerDimension = this._getElementDimension(this._config.center);
|
||||
if (!this._isOverlapping(centerDimension, dimensionContainer, allDimensions)) {
|
||||
dimensions.push({
|
||||
left: centerDimension.left,
|
||||
top: centerDimension.top,
|
||||
width: centerDimension.width,
|
||||
height: centerDimension.height
|
||||
});
|
||||
// render debug element
|
||||
this._showDebugElement(centerDimension, 0);
|
||||
|
||||
maxResults--;
|
||||
}
|
||||
}
|
||||
|
||||
// increase the "gab" between center element and potential found dimensions...
|
||||
// ... for each recursive loop call, to get an elliptical cycle beyond
|
||||
// -> defaultGab for 1. loop, ..., defaultGab + 3 * defaultGab/ 2 for 3. loop
|
||||
this._config.gapX = this._config.defaultGapX + loops * Math.round(this._config.defaultGapX / 2);
|
||||
this._config.gapY = this._config.defaultGapY + loops * Math.round(this._config.defaultGapY / 2);
|
||||
this._config.gapX = this._config.defaultGapX + (loops - 1) * 20;
|
||||
this._config.gapY = this._config.defaultGapY + (loops - 1) * 20;
|
||||
let centerDimension = this._getElementDimension(this._config.center);
|
||||
|
||||
do {
|
||||
while(maxResults > 0 && start < end){
|
||||
// get all potential coordinates on an eclipse around a given "centerElementDimension"
|
||||
let coordinate = this._getEllipseCoordinates(centerDimension, end);
|
||||
// transform relative x/y coordinate into a absolute 2D area
|
||||
@@ -264,7 +323,7 @@ define(() => {
|
||||
maxResults--;
|
||||
}
|
||||
end -= angle;
|
||||
} while (maxResults > 0 && start < end);
|
||||
}
|
||||
|
||||
if(maxResults > 0 && loops < this._config.loops){
|
||||
loops++;
|
||||
|
||||
@@ -10,6 +10,7 @@ define([
|
||||
'bootbox',
|
||||
'app/map/util',
|
||||
'app/map/system',
|
||||
'app/map/layout',
|
||||
'app/map/magnetizing',
|
||||
'app/map/scrollbar',
|
||||
'dragToSelect',
|
||||
@@ -17,7 +18,7 @@ define([
|
||||
'app/map/contextmenu',
|
||||
'app/map/overlay',
|
||||
'app/map/local'
|
||||
], function($, Init, Util, Render, bootbox, MapUtil, System, MagnetizerWrapper) {
|
||||
], function($, Init, Util, Render, bootbox, MapUtil, System, Layout, MagnetizerWrapper) {
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -2661,6 +2662,24 @@ define([
|
||||
switch(action){
|
||||
case 'add_system':
|
||||
// add new system dialog
|
||||
let grid = [MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension];
|
||||
let positionFinder = new Layout.Position({
|
||||
container: currentMapElement[0],
|
||||
center: [position.x, position.y],
|
||||
loops: 5,
|
||||
defaultGapX: 10,
|
||||
defaultGapY: 10,
|
||||
grid: currentMapElement.hasClass(MapUtil.config.mapGridClass) ? grid : false,
|
||||
debug: false
|
||||
});
|
||||
|
||||
let dimensions = positionFinder.findNonOverlappingDimensions(1, 8);
|
||||
|
||||
if(dimensions.length){
|
||||
position.x = dimensions[0].left;
|
||||
position.y = dimensions[0].top;
|
||||
}
|
||||
|
||||
showNewSystemDialog(currentMap, {position: position});
|
||||
break;
|
||||
case 'select_all':
|
||||
|
||||
@@ -309,7 +309,7 @@ define([
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
|
||||
let position = new Layout.Position({
|
||||
let positionFinder = new Layout.Position({
|
||||
container: mapContainer[0],
|
||||
center: sourceSystem[0],
|
||||
loops: 4,
|
||||
@@ -317,7 +317,7 @@ define([
|
||||
debug: false
|
||||
});
|
||||
|
||||
let dimensions = position.findNonOverlappingDimensions(1, 16);
|
||||
let dimensions = positionFinder.findNonOverlappingDimensions(1, 16);
|
||||
if(dimensions.length){
|
||||
//... empty map space found
|
||||
x = dimensions[0].left;
|
||||
|
||||
@@ -40,18 +40,48 @@ define(() => {
|
||||
*/
|
||||
this._getElementDimension = (element) => {
|
||||
let dim = null;
|
||||
if(element){
|
||||
// add "gap" to a and b in order to have some space around elements
|
||||
dim = {
|
||||
left: element.style.left ? parseInt(element.style.left, 10) : 0,
|
||||
top: element.style.top ? parseInt(element.style.top, 10) : 0,
|
||||
a: parseInt((element.offsetWidth / 2).toString(), 10) + this._config.gapX,
|
||||
b: parseInt((element.offsetHeight / 2).toString(), 10) + this._config.gapY,
|
||||
width: element.offsetWidth,
|
||||
height: element.offsetHeight
|
||||
};
|
||||
|
||||
let left = 0;
|
||||
let top = 0;
|
||||
let a = 0;
|
||||
let b = 0;
|
||||
let width = this._config.newElementWidth;
|
||||
let height = this._config.newElementHeight;
|
||||
|
||||
if(Array.isArray(element)){
|
||||
// xy coordinates
|
||||
let point = [
|
||||
element[0] ? parseInt(element[0], 10) : 0,
|
||||
element[1] ? parseInt(element[1], 10) : 0
|
||||
];
|
||||
|
||||
if(this._config.grid){
|
||||
point = this._transformPointToGrid(point);
|
||||
}
|
||||
|
||||
left = point[0];
|
||||
top = point[1];
|
||||
a = this._config.gapX ;
|
||||
b = this._config.gapY ;
|
||||
}else if(element){
|
||||
// DOM element
|
||||
left = element.style.left ? parseInt(element.style.left, 10) : 0;
|
||||
top = element.style.top ? parseInt(element.style.top, 10) : 0;
|
||||
a = parseInt((element.offsetWidth / 2).toString(), 10) + this._config.gapX;
|
||||
b = parseInt((element.offsetHeight / 2).toString(), 10) + this._config.gapY;
|
||||
width = element.offsetWidth;
|
||||
height = element.offsetHeight;
|
||||
}
|
||||
return dim;
|
||||
|
||||
// add "gap" to a and b in order to have some space around elements
|
||||
return {
|
||||
left: left,
|
||||
top: top,
|
||||
a: a,
|
||||
b: b,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -96,6 +126,18 @@ define(() => {
|
||||
return dimensions;
|
||||
};
|
||||
|
||||
/**
|
||||
* transform a x/y point into a x/y point that snaps to grid
|
||||
* @param point
|
||||
* @returns {*}
|
||||
* @private
|
||||
*/
|
||||
this._transformPointToGrid = (point) => {
|
||||
point[0] = Math.floor(point[0] / this._config.grid[0]) * this._config.grid[0];
|
||||
point[1] = Math.floor(point[1] / this._config.grid[1]) * this._config.grid[1];
|
||||
return point;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform a x/y coordinate into a 2D element with width/height
|
||||
* @param centerDimension
|
||||
@@ -136,8 +178,9 @@ define(() => {
|
||||
|
||||
// transform to grid coordinates (if grid snapping is enabled) ------------------------------------
|
||||
if(this._config.grid){
|
||||
left = Math.floor(left / this._config.grid[0]) * this._config.grid[0];
|
||||
top = Math.floor(top / this._config.grid[1]) * this._config.grid[1];
|
||||
let point = this._transformPointToGrid([left, top]);
|
||||
left = point[0];
|
||||
top = point[1];
|
||||
}
|
||||
|
||||
dim = {
|
||||
@@ -239,14 +282,30 @@ define(() => {
|
||||
steps = steps || 1;
|
||||
loops = loops || 1;
|
||||
|
||||
if(loops === 1){
|
||||
// check center element
|
||||
let centerDimension = this._getElementDimension(this._config.center);
|
||||
if (!this._isOverlapping(centerDimension, dimensionContainer, allDimensions)) {
|
||||
dimensions.push({
|
||||
left: centerDimension.left,
|
||||
top: centerDimension.top,
|
||||
width: centerDimension.width,
|
||||
height: centerDimension.height
|
||||
});
|
||||
// render debug element
|
||||
this._showDebugElement(centerDimension, 0);
|
||||
|
||||
maxResults--;
|
||||
}
|
||||
}
|
||||
|
||||
// increase the "gab" between center element and potential found dimensions...
|
||||
// ... for each recursive loop call, to get an elliptical cycle beyond
|
||||
// -> defaultGab for 1. loop, ..., defaultGab + 3 * defaultGab/ 2 for 3. loop
|
||||
this._config.gapX = this._config.defaultGapX + loops * Math.round(this._config.defaultGapX / 2);
|
||||
this._config.gapY = this._config.defaultGapY + loops * Math.round(this._config.defaultGapY / 2);
|
||||
this._config.gapX = this._config.defaultGapX + (loops - 1) * 20;
|
||||
this._config.gapY = this._config.defaultGapY + (loops - 1) * 20;
|
||||
let centerDimension = this._getElementDimension(this._config.center);
|
||||
|
||||
do {
|
||||
while(maxResults > 0 && start < end){
|
||||
// get all potential coordinates on an eclipse around a given "centerElementDimension"
|
||||
let coordinate = this._getEllipseCoordinates(centerDimension, end);
|
||||
// transform relative x/y coordinate into a absolute 2D area
|
||||
@@ -264,7 +323,7 @@ define(() => {
|
||||
maxResults--;
|
||||
}
|
||||
end -= angle;
|
||||
} while (maxResults > 0 && start < end);
|
||||
}
|
||||
|
||||
if(maxResults > 0 && loops < this._config.loops){
|
||||
loops++;
|
||||
|
||||
@@ -10,6 +10,7 @@ define([
|
||||
'bootbox',
|
||||
'app/map/util',
|
||||
'app/map/system',
|
||||
'app/map/layout',
|
||||
'app/map/magnetizing',
|
||||
'app/map/scrollbar',
|
||||
'dragToSelect',
|
||||
@@ -17,7 +18,7 @@ define([
|
||||
'app/map/contextmenu',
|
||||
'app/map/overlay',
|
||||
'app/map/local'
|
||||
], function($, Init, Util, Render, bootbox, MapUtil, System, MagnetizerWrapper) {
|
||||
], function($, Init, Util, Render, bootbox, MapUtil, System, Layout, MagnetizerWrapper) {
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -2661,6 +2662,24 @@ define([
|
||||
switch(action){
|
||||
case 'add_system':
|
||||
// add new system dialog
|
||||
let grid = [MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension];
|
||||
let positionFinder = new Layout.Position({
|
||||
container: currentMapElement[0],
|
||||
center: [position.x, position.y],
|
||||
loops: 5,
|
||||
defaultGapX: 10,
|
||||
defaultGapY: 10,
|
||||
grid: currentMapElement.hasClass(MapUtil.config.mapGridClass) ? grid : false,
|
||||
debug: false
|
||||
});
|
||||
|
||||
let dimensions = positionFinder.findNonOverlappingDimensions(1, 8);
|
||||
|
||||
if(dimensions.length){
|
||||
position.x = dimensions[0].left;
|
||||
position.y = dimensions[0].top;
|
||||
}
|
||||
|
||||
showNewSystemDialog(currentMap, {position: position});
|
||||
break;
|
||||
case 'select_all':
|
||||
|
||||
@@ -309,7 +309,7 @@ define([
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
|
||||
let position = new Layout.Position({
|
||||
let positionFinder = new Layout.Position({
|
||||
container: mapContainer[0],
|
||||
center: sourceSystem[0],
|
||||
loops: 4,
|
||||
@@ -317,7 +317,7 @@ define([
|
||||
debug: false
|
||||
});
|
||||
|
||||
let dimensions = position.findNonOverlappingDimensions(1, 16);
|
||||
let dimensions = positionFinder.findNonOverlappingDimensions(1, 16);
|
||||
if(dimensions.length){
|
||||
//... empty map space found
|
||||
x = dimensions[0].left;
|
||||
|
||||
Reference in New Issue
Block a user