diff --git a/src/system/clustergenerator.service.ts b/src/system/clustergenerator.service.ts index 29f7746..18eb2a0 100644 --- a/src/system/clustergenerator.service.ts +++ b/src/system/clustergenerator.service.ts @@ -117,6 +117,23 @@ export class ClusterGeneratorService { return false; } + nearestSystems(cluster1:System[], cluster2: System[]): System[]{ + let nearestSystems: System[] = []; + let nearestSystemDistance = Infinity; + + for(const system1 of cluster1){ + for(const system2 of cluster2){ + const distance = Math.hypot(system1.x - system2.x, system1.y - system2.y); + if(distance < nearestSystemDistance){ + nearestSystems = [system1, system2]; + nearestSystemDistance = distance; + } + } + } + + return nearestSystems; + } + connectSystems(system1: System, system2: System): void { const distance = Math.hypot(system1.x - system2.x, system1.y - system2.y); system1.links[system2._id.toString()] = distance; diff --git a/src/system/systemgenerator.service.ts b/src/system/systemgenerator.service.ts index 68c4e88..d013b89 100644 --- a/src/system/systemgenerator.service.ts +++ b/src/system/systemgenerator.service.ts @@ -62,12 +62,12 @@ export class SystemGeneratorService { //Connect clusters this.connectClusters(clusters, clustersCenter, avgRadius*3); - //Remove systems with no neighbors - for(let i = 0; i < clusters.length; i++){ - clusters[i] = clusters[i].filter(system => Object.keys(system.links).length > 0); - } + // //Remove systems with no neighbors + // for(let i = 0; i < clusters.length; i++){ + // clusters[i] = clusters[i].filter(system => Object.keys(system.links).length > 0); + // } - return clusters.flat(); + return this.connectSingleSystems(clusters.flat()); } private moveCluster(cluster: System[], movement: number[]): System[] { @@ -188,18 +188,7 @@ export class SystemGeneratorService { * Connects the two nearest systems of two clusters * */ private connectCluster(cluster1: System[], cluster2: System[], connectedSystems: System[]) : boolean { - let nearestSystems: System[] = []; - let nearestSystemDistance = -1; - - for(const system1 of cluster1){ - for(const system2 of cluster2){ - const distance = Math.hypot(system1.x - system2.x, system1.y - system2.y); - if(nearestSystemDistance === -1 || distance < nearestSystemDistance){ - nearestSystems = [system1, system2]; - nearestSystemDistance = distance; - } - } - } + const nearestSystems: System[] = this.clusterGenerator.nearestSystems(cluster1, cluster2); if(!this.isEdgeIntersecting(nearestSystems, connectedSystems)){ connectedSystems.push(nearestSystems[0]); @@ -211,40 +200,6 @@ export class SystemGeneratorService { return false; } - // private removeIntersectingEdges(systems: System[]): System[] { - // for(let i = 0; i < systems.length; i++) { - // for(let j = i+1; j < systems.length; j++) { - // this.checkLinks(systems, i, j); - // } - // } - // - // return systems; - // } - // - // /** - // * Checks if two systems have links that intersect with each other - // */ - // private checkLinks(systems: System[], system1: number, system2: number) { - // const links1:System[][] = Array.from(Object.keys(systems[system1].links).map(key => { - // const otherSystem = systems.find(system => system._id.toString() === key)!; - // return [systems[system1], otherSystem]; - // })); - // - // for(const key of Object.keys(systems[system2].links)){ - // const system = systems.find(system => system._id.toString() === key)!; - // if(system._id.toString() === systems[system1]._id.toString()) continue; - // - // const link2 = [systems[system2], system]; - // const link1 = links1.find(link1 => - // link1[1]._id.toString() !== system._id.toString() && link1[1]._id.toString() !== systems[system2]._id.toString() && this.areEdgesIntersecting(link1, link2)); - // - // if(link1){ - // this.removeLink(systems[system2], system); - // break; - // } - // } - // } - private isEdgeIntersecting(link: System[], systems: System[]) : boolean{ for(let i = 0; i < systems.length; i++) { for(let j = i+1; j < systems.length; j++) { @@ -280,8 +235,43 @@ export class SystemGeneratorService { return uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1; } - private removeLink(system1: System, system2: System) { - delete system1.links[system2._id.toString()]; - delete system2.links[system1._id.toString()]; + private connectSingleSystems(system: System[]): System[]{ + const unvisited: System[] = system; + + const visited: System[] = []; + + + while(unvisited.length > 0){ + const nextUnvisited = unvisited[Math.randInt(unvisited.length)]; + + //Check if this is not the first round of the loop + if(visited.length != 0){ + //Connect the nearest systems of the new system to the existing connected systems + const nearestSystems = this.clusterGenerator.nearestSystems([nextUnvisited], visited) + this.clusterGenerator.connectSystems(nearestSystems[0], nearestSystems[1]); + } + + const queue: System[] = [nextUnvisited]; + + while (queue.length > 0) { + const current = queue.shift(); + if (!current) break; + + //Add neighbors to the queue + for(const neighbor of Object.keys(current.links) + .map(id => system.find(s => s._id.toString() === id)) + .filter(s => s && !visited.includes(s))) + { + if(neighbor) queue.push(neighbor); + } + + if(!visited.includes(current)){ + visited.push(current); + unvisited.splice(unvisited.indexOf(current), 1); + } + } + } + + return visited; } }