【JS绘制Voronoi图 - 2】两个Voronoi图干涉

假设我手上两个Voronoi图
一个五个关键点
一个五十个关键点。
五个关键点
五十个关键点
我们重新调整五十个关键点的图的上色情况。
我们对图二进行重新上色,如果图二中的关键点在图一中落入某一颜色,则让图二该颜色区域也为这个颜色。
注意可能有人注意到,图二的Voronio图有生成点问题,某些区域不正确,这是由于前期代码有点bug导致的。上一章代码做了注释,注明了产生bug原因
结果
在这里插入图片描述
可以看到图一直来直去的边界变得有变化了,其实图二关键点越多,变化的细节就越多。
也可以更多图进行重新覆盖。
上代码
前端代码

<!DOCTYPE HTML>
<html>
	<head>
		<script src="./js/Voronoi.js" type="text/javascript"></script>
	</head>
	<body>
		<main>
		</main>

		<script type="text/javascript">
		var width = 250;
		var height = 250;
		var main = document.getElementsByTagName('main')[0];
		var canvas = document.createElement('canvas');
		canvas.width = width;
		canvas.height = height;
		main.appendChild(canvas);

		// var p = new Point(100,200);
		// alert(p.getX());
		//draw

		var cxt=canvas.getContext("2d");
		
		var vor1 = new Voronoi(width,height,4);
		//var vor2 = new Voronoi(width,height,50);
		var vor4 = new Voronoi(width,height,50);

		//drawVoronoi(cxt,vor1);
		//vor1.getColorMap().set(0,"#000000");
		//Overlay(vor1,vor2);
		Overlay(vor1,vor4);
		//alert(vor1.getKeyPointNum());
		drawVoronoi(cxt,vor4);

		console.log("over");
		</script>

</body>
</html>

//class Voronoi
function Voronoi(widthG,heightG,keyPointNumG){
    var width = 0;
    var height = 0;
    var keyPointNum = 0;
    var keyPointAry = new Array();
    var colorMap = new Map();
    //构造函数
    var init = function(){
        width = widthG;
        height = heightG;
        keyPointNum = keyPointNumG;
        randomKeyPoint();
    }
    //随机生成点 以及该点对应的颜色
    var randomKeyPoint = function(){
        for(var i =0 ; i <keyPointNum ; i++){
            var tmpPoint = new Point(0,0);
            tmpPoint.randomPoint(width,height);
            keyPointAry.push(tmpPoint);
            //set color
            var color = Math.floor(Math.random() * 16777216).toString(16);
            ///
            //图二中图片填充错误是由于没有下句代码导致,因为有时候生成的16进制数字没有不能达到6个字符。 比如 255 就为 FF
            //导致颜色为 #FF,导致填充失败。所以我们加个不足六位的 0补齐。
            while(color.length<6){
                color = "0" + color;
            }
            ///
            color = "#" + color;
            colorMap.set(i,color);
        }
    }
    this.getColor = function(p1){
        //先找到最近点
        var dis = -1;
        var nearPointID = 0;
        for(var m = 0 ; m < keyPointNum ; m++){
            var tmpDis = PointDis(p1,keyPointAry[m]);
            if(dis < 0){
                dis = tmpDis;
            }
            if(tmpDis<dis){
                dis = tmpDis;
                nearPointID = m;
            }
        }
        return colorMap.get(nearPointID);
    }
    //绘出随机点
    this.drawKeyPoint = function(){
        for(var i =0 ; i <keyPointNum ; i++){
            cxt.fillStyle = "#000000";
            cxt.fillRect(keyPointAry[i].getX(),keyPointAry[i].getY(),2,2);
        }
    }
    this.getKeyPointNum = function(){
        return keyPointNum;
    }
    this.getKeyPointAry = function(){
        return keyPointAry;
    }
    this.getColorMap = function(){
        return colorMap;
    }
    this.getWidth = function(){
        return width;
    }
    this.getHeight= function(){
        return height;
    }
    init();
}
//两个Voronoi叠加
function Overlay(v1,v2){
    for(var i = 0 ; i<v2.getKeyPointNum() ; i++){
        var color = v1.getColor(v2.getKeyPointAry()[i]);
        //console.log(color);
        //测试用假设 "#00CCFF" 为海洋则不叠加
        v2.getColorMap().set(i,color);
        // if(color == "#000000"){
        //     v2.getColorMap().set(i,"#00CCFF");
        // }else if(color != "#00CCFF"){
        //     v2.getColorMap().set(i,color);
        // }
    }
    console.log("an overlay complete");
}
function drawVoronoi(contextDraw,voronoi){
    for(var i = 0; i < voronoi.getWidth() ; i++){
        for(var j = 0; j <voronoi.getHeight() ; j++){
            contextDraw.fillStyle = voronoi.getColor(new Point(i,j));
            contextDraw.fillRect(i,j,1,1);
        }
    }
    voronoi.drawKeyPoint();
}

//其他工具类


//class point start
function Point(ax,ay){
    var x = 0;
    var y = 0;
    var init = function(){
        x = ax;
        y = ay;
    }
    this.getX = function(){
        return x;
    }
    this.getY = function(){
        return y
    }
    this.setPoint = function(p1){
        x = p1.getX();
        y = p1.getY();
    }
    this.randomPoint = function(width,height){
        x = Math.round(Math.random() * width); 
        y = Math.round(Math.random() * height); 
    }
    this.isReal = function(){
        return x!=-1&&y!=-1;
    }
    init();
}
//计算出点的距离函数
function PointDis(p1,p2){
    return Math.sqrt((Math.pow((p1.getX() - p2.getX()),2) + Math.pow((p1.getY() - p2.getY()),2)));
}
//class point end
//


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值