多边形类

const Point=require('./Point')
const Line=require('./Line')
//多边形类
function Polygon(a) {
    if(this instanceof Polygon){
        this.n=a.length;
        this.a=a;
    }else{
        if(a.every(function (item) {
            return item instanceof Point
        })){
            return new Polygon(a)
        }else{
            throw 'Polygon 参数错误'
        }
    }
}
Polygon.prototype={
    //计算多边形周长
    perimeter:function(){
        let sum=0;
        for (let i=0;i<this.n;i++){
            sum=sum+Point.sub(this.a[(i+1)%this.n],this.a[i]).norm();
        }
        return sum;
    },
    //计算多边形面积
    area:function () {
        let sum=0;
        for(let i=0;i<this.n;i++){
            sum=sum+Point.det(this.a[((i+1)%this.n)],this.a[i])
        }
        return sum/2
    },
    //判断点是否在多边形内部
    pointIn:function (t) {
        let num=0;
        const a=this.a;
        const n=this.n;
        for(let i=0;i<n;i++){
            if(Line.pointOnSegment(t,a[i],a[(i+1)%n])){
                return 2;
            }
            const k=Math.cmp(Point.det(Point.sub(a[(i+1)%n],a[i]),Point.sub(t,a[i])))
            const d1=Math.cmp(a[i].y-t.y);
            const d2=Math.cmp(a[(i+1)%n].y-t.y);
            if(k>0&&d1<=0&&d2>0){
                num++
            }
            if(k<0&&d2<=0&&d1>0){
                num++
            }
        }
        return num!==0;
    }
}

// 多边形的重心
Polygon.prototype.massCenter=function () {
    let n=this.n;
    let a=this.a;
    let ans=Point(0,0);
    if(Math.cmp(this.area())===0){
        return ans;
    }
    for(let i=0;i<n;i++){
        ans=Point.add(ans,Point.multiply(Point.add(a[i],a[(i+1)%n]),Point.det(a[(i+1)%n],a[i])));
    }
    return Point.divide(ans,this.area()*6)
}

module.exports=Polygon;

//demo
// const poly=Polygon([Point(-2,-1),Point(0,0),Point(1,-1),Point(0,-2),])
// console.log(poly.area())
// console.log(poly.pointIn(Point(0,0)))
// console.log(poly.massCenter());

 

posted @ 2019-03-14 16:51  无工时代  阅读(227)  评论(0编辑  收藏  举报