<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>二值轮矩阵粗轮廓提取工具</title>
<style>
body {text-align:center;font-family:Arial;margin:20px;}
canvas {border:2px solid #333;margin:10px auto;display:block;background:#fff;}
button {padding:8px 20px;font-size:16px;cursor:pointer;background:#4CAF50;color:white;border:none;border-radius:4px;}
button:hover {background:#45a049;}
.container {width:800px;margin:0 auto;}
</style>
</head>
<body>
<div class="container">
<h3>原图(多边形+圆形混合)</h3>
<canvas id="original" width="400" height="300"></canvas>
<h3>粗彩色轮廓图(轮矩阵"甩"除内部)</h3>
<canvas id="outline" width="400" height="300"></canvas>
<button onclick="reset()">重置生成图形</button>
</div>
<script>
let oCtx = original.getContext('2d'), lCtx = outline.getContext('2d');
// 生成多边形+圆形混合图形
function drawRandomGraph() {
oCtx.clearRect(0,0,400,300);
// 随机多边形
for(let k=0;k<4;k++){
let n=3+Math.floor(Math.random()*5),x0=200+(Math.random()-0.5)*80,y0=150+(Math.random()-0.5)*80;
oCtx.beginPath();
for(let i=0;i<n;i++) oCtx.lineTo(x0+Math.cos(i/n*2*Math.PI)*(30+k*15),y0+Math.sin(i/n*2*Math.PI)*(30+k*15));
oCtx.closePath();
oCtx.fillStyle=`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255})`;
oCtx.fill();
}
// 嵌入小圆形
for(let i=0;i<3;i++){
let r=15+Math.random()*10,x=150+Math.random()*100,y=100+Math.random()*100;
oCtx.beginPath();oCtx.arc(x,y,r,0,2*Math.PI);
oCtx.fillStyle=`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255})`;
oCtx.fill();
}
}
// 二值轮矩阵旋转"甩"动提取粗轮廓
function extractOutline() {
lCtx.clearRect(0,0,400,300);
let imgData=oCtx.getImageData(0,0,400,300),data=imgData.data,w=400,h=300;
// 轮矩阵:动态旋转中心,环形权重扩大边缘范围
function wheelMatrix(x,y,cx,cy,angle) {
let dx=x-cx, dy=y-cy;
let rotX=dx*Math.cos(angle)-dy*Math.sin(angle); // 矩阵旋转
let dist=Math.sqrt(rotX**2+dy**2);
return dist%10 < 4 ? 1 : 0; // 扩大权重范围实现粗轮廓
}
// 多轮旋转"甩"动,逐轮偏移中心
for(let round=0;round<5;round++){
let angle=round*Math.PI/4, cx=200+round*12, cy=150+round*8;
for(let y=0;y<h;y++)for(let x=0;x<w;x++){
let i=(y*w+x)*4;
if(!wheelMatrix(x,y,cx,cy,angle)) continue;
// 16邻域边缘检测,扩大范围实现粗线条
let isEdge=false;
for(let dy=-2;dy<=2;dy++)for(let dx=-2;dx<=2;dx++){
if(dx===0&&dy===0) continue;
let nx=x+dx, ny=y+dy;
if(nx>=0&&nx<w&&ny>=0&&ny<h){
let ni=(ny*w+nx)*4;
isEdge|=Math.abs(data[i]-data[ni])>15||Math.abs(data[i+1]-data[ni+1])>15||Math.abs(data[i+2]-data[ni+2])>15;
}
}
data[i+3]=isEdge?255:0; // 非边缘完全透明
}
}
lCtx.putImageData(imgData,0,0);
}
function reset(){drawRandomGraph();extractOutline();}
reset();
</script>
</body>
</html>