RustX/Autonomous_Driving_Simulation
3
1class Visualizer{2 static drawNetwork(ctx,network){3 const margin=50;4 const left=margin;5 const top=margin;6 const width=ctx.canvas.width-margin*2;7 const height=ctx.canvas.height-margin*2;8 9 const levelHeight=height/network.levels.length;10 11 for(let i=network.levels.length-1;i>=0;i--){12 const levelTop=top+13 lerp(14 height-levelHeight,15 0,16 network.levels.length==117 ?0.518 :i/(network.levels.length-1)19 );20 21 Visualizer.drawLevel(ctx,network.levels[i],22 left,levelTop,23 width,levelHeight,24 i==network.levels.length-125 ?['Up','Left','Right','Down']26 :[]27 );28 }29 }30 31 static drawLevel(ctx,level,left,top,width,height,outputLabels){32 const right=left+width;33 const bottom=top+height;34 35 const {inputs,outputs,weights,biases}=level;36 const nodeRadius=14;37 38 for(let i=0;i<inputs.length;i++){39 for(let j=0;j<outputs.length;j++){40 ctx.beginPath();41 ctx.moveTo(42 Visualizer.#getNodeX(inputs,i,left,right),43 bottom44 );45 ctx.lineTo(46 Visualizer.#getNodeX(outputs,j,left,right),47 top48 );49 ctx.lineWidth=2;50 ctx.strokeStyle=getRGBA(weights[i][j]);51 ctx.stroke();52 }53 }54 for(let i=0;i<inputs.length;i++){55 const x=Visualizer.#getNodeX(inputs,i,left,right);56 ctx.beginPath();57 ctx.arc(x,bottom,nodeRadius,0,Math.PI*2);58 ctx.fillStyle="black";59 ctx.fill();60 ctx.beginPath();61 ctx.arc(x,bottom,nodeRadius*0.6,0,Math.PI*2);62 ctx.fillStyle=getRGBA(inputs[i]);63 ctx.fill();64 }65 for(let i=0;i<outputs.length;i++){66 const x=Visualizer.#getNodeX(outputs,i,left,right);67 ctx.beginPath();68 ctx.arc(x,top,nodeRadius,0,Math.PI*2);69 ctx.fillStyle="black";70 ctx.fill();71 ctx.beginPath();72 ctx.arc(x,top,nodeRadius*0.6,0,Math.PI*2);73 ctx.fillStyle=getRGBA(outputs[i]);74 ctx.fill();75 ctx.beginPath();76 ctx.lineWidth=2;77 ctx.arc(x,top,nodeRadius*0.8,0,Math.PI*2);78 ctx.strokeStyle=getRGBA(biases[i]);79 ctx.stroke();80 if(outputLabels[i]){81 ctx.beginPath();82 ctx.textAlign="center";83 ctx.textBaseline="middle";84 ctx.fillStyle="black";85 ctx.strokeStyle="white";86 ctx.font=(nodeRadius*1.5)+"px Arial";87 ctx.fillText(outputLabels[i],x,88 top+nodeRadius*0.1);89 ctx.lineWidth=0.5;90 ctx.strokeText(outputLabels[i],x,91 top+nodeRadius*0.1);92 }93 }94 }95 96 static #getNodeX(nodes,index,left,right){97 return lerp(98 left,99 right,100 nodes.length==1101 ?0.5102 :index/(nodes.length-1)103 );104 }105}