一道算法题

假定二维空间平面内有n个圆,现在我们需要将存在交集的圆进行分组,输出结果为n个组,每个组包含i个圆.
交集算法: 两圆心的距离 小于 两圆半径之和.
假设圆数据为: (用数组表示圆)

[
    { X: 0, Y: 0, Radius: 1 },
    { X: 3, Y: 2, Radius: 2 },
    { X: 2, Y: 1, Radius: 3 },
    { X: 5, Y: 2, Radius: 4 },
    { X: 1, Y: 3, Radius: 5 },
    { X: 2, Y: 4, Radius: 6 },
    { X: 2323, Y: 121, Radius: 7 },
    { X: 2323, Y: 121, Radius: 7 },
    { X: 2322, Y: 121, Radius: 7 },
]

那么输出的结果为:

​​​​​[ [ { X: 0, Y: 0, Radius: 1 },​​​​​
​​​​​    { X: 2, Y: 1, Radius: 3 },​​​​​
​​​​​    { X: 1, Y: 3, Radius: 5 },​​​​​
​​​​​    { X: 2, Y: 4, Radius: 6 },​​​​​
​​​​​    { X: 3, Y: 2, Radius: 2 },​​​​​
​​​​​    { X: 5, Y: 2, Radius: 4 } ],​​​​​
​​​​​  [ { X: 2323, Y: 121, Radius: 7 },​​​​​
​​​​​    { X: 2323, Y: 121, Radius: 7 },​​​​​
​​​​​    { X: 2322, Y: 121, Radius: 7 } ] ]​​​​​

假设代码结构为如下:

    { X: 1, Y: 0.7, Radius: 0.6 },
    { X: 0, Y: 0, Radius: 0.6 },
    { X: 1, Y: 0, Radius: 0.5 },

//圆1和圆2并不交集
//圆2和圆3存在交集
//圆1和圆3存在交集

//那么结果为
[cir1,cir2,cir3]//他们应该是一组的.

用JavaScript设计代码并实现

//圆类
class Circle {
    constructor (id, x, y, r) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.radius = r;
    }
}
//计算圆心距
function computeCenDist (circle1, circle2) {
    let x = circle1.x - circle2.x;
    let y = circle1.y - circle2.y;
    return Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
}
//计算半径和
function computeRadiusSum (circle1, circle2) {
    return circle1.radius + circle2.radius;
}
//构造圆类对象数组
let input = [ { X: 0, Y: 0, Radius: 1 },
    { X: 3, Y: 2, Radius: 2 },
    { X: 2, Y: 1, Radius: 3 },
    { X: 5, Y: 2, Radius: 4 },
    { X: 1, Y: 3, Radius: 5 },
    { X: 2, Y: 4, Radius: 6 },
    { X: 2323, Y: 121, Radius: 7 },
    { X: 2323, Y: 121, Radius: 7 },
    { X: 2322, Y: 121, Radius: 7 },];
let circle = new Array(input.length);
let id = 0;
for(let i = 0;i < input.length;i++){
    let x = input[i].X;
    let y = input[i].Y;
    let r = input[i].Radius;
    circle[i] = new Circle(id, x, y ,r);
    id++;
}
//进行圆的分组
let classifiedId  = [];
let output = [];
for(let i = 0;i < circle.length;i++){
    let group = [];
    //判断待分组圆是否已在分组中
    if(classifiedId.indexOf(circle[i].id) == -1) {
        classifiedId.push(circle[i].id);
        group.push(circle[i]);
        //把与该圆有交集的圆归为一组
        for(let j = i + 1;j < circle.length ;j++){
            if(computeCenDist(circle[i], circle[j]) < computeRadiusSum(circle[i], circle[j])){
                classifiedId.push(circle[j].id);
                group.push(circle[j]);
            }
        }
        let flag = false;
        //将新分组与已有分组进行合并
        for(let key in output) {
            let o = new Set(output[key]);
            if(group.filter(x => o.has(x)).length != 0) {
                output[key] = Array.from(new Set([...group, ...output[key]]));
                flag = true;
                break;
            }
        }
        if(!flag){
            output.push(group);
        }
    }
}
//输出圆的分组结果
console.log(JSON.stringify(output));
posted @ 2021-04-04 11:02  大萌神  阅读(106)  评论(0编辑  收藏  举报