大学时候,有上过关于图像学相关的课程,当时图像学课程的老师,听说在学院里都非常的出名,在入学之前就有听说,当初信誓旦旦的,想好好学习,可以还是挡不过大学里的自由的生活的诱惑,还是没能坚持下来。
当初对图形学相关的印象也是停留在绚丽的图形图像上,对于实现感觉就是高深莫测的东西(刁吊的MFC),现在工作也快一年多了,可能是东西做的多了,对做任何东西都有一股自信,所以想把当初的东西捡起来。
原理:(摘自百度百科)
1.取一个实心的三角形。(多数使用等边三角形)
2.沿三边中点的连线,将它分成四个小三角形。
3.去掉中间的那一个小三角形。
4.对其余三个小三角形重复1。
取一个正方形或其他形状开始,用类似的方法构作,形状也会和谢尔宾斯基三角形相近。
先贴上js实现效果:
迭代效果
关键代码:
页面:
使用HTML5中的canvas画布进行图像的绘制,并提供一个可供输入的文本框记录迭代次数。
<body style=‘margin:0 auto;width:800px;‘> <div> <input type=‘text‘ id=‘Count‘/><input type=‘button‘ value=‘运行‘ id=‘btn‘ /> </div> <canvas id=‘cav‘ width=‘500‘ height=‘500‘ style=‘border:1px solid black;‘></canvas> </body>
js实现思路:
定义最大的等边三角形,每迭代一次,取三角各边的中点,然后将中间点进行连接,对于中间的三角形不进行二次迭代,使用此取巧的方式代替“挖空”中间三角形的概念,逻辑很简单。
js:
1、点对象
function point (x,y) { this.x = x; this.y = y; }
2、画线
function drawLine (ctx,point1,point2,point3) { ctx.beginPath(); ctx.moveTo(point1.x, point1.y); ctx.lineTo(point2.x, point2.y); ctx.lineTo(point3.x, point3.y); ctx.closePath(); ctx.stroke(); }
3、取中间点
function getMiddlePoint (pointA,pointB) { var x = (pointA.x + pointB.x)/2; var y = (pointA.y + pointB.y)/2; return new point(x,y); }
4、迭代函数
function drawOri (ctx,pointA,pointB,pointC,count) { if (count>2) { drawLine(ctx,pointA,pointB,pointC); var t_A = getMiddlePoint(pointA,pointB); var t_B = getMiddlePoint(pointA,pointC); var t_C = getMiddlePoint(pointB,pointC); count -= 1; drawOri(ctx,t_A,pointB,t_C,count); drawOri(ctx,t_A,t_B,pointA,count); drawOri(ctx,pointC,t_B,t_C,count); } else if(count==2){ drawLine(ctx,pointA,pointB,pointC); var t_A = getMiddlePoint(pointA,pointB); var t_B = getMiddlePoint(pointA,pointC); var t_C = getMiddlePoint(pointB,pointC); count -= 1; drawOri(ctx,t_A,t_B,t_C,count); }else{ drawLine(ctx,pointA,pointB,pointC); } }
完整可运行代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset=‘utf-8‘></meta>
<title>谢尔宾斯基三角形</title>
<style type="text/css"></style>
<script type="text/javascript">
function point (x,y) {
this.x = x;
this.y = y;
}
function drawLine (ctx,point1,point2,point3) {
ctx.beginPath();
ctx.moveTo(point1.x, point1.y);
ctx.lineTo(point2.x, point2.y);
ctx.lineTo(point3.x, point3.y);
ctx.closePath();
ctx.stroke();
}
function getMiddlePoint (pointA,pointB) {
var x = (pointA.x + pointB.x)/2;
var y = (pointA.y + pointB.y)/2;
return new point(x,y);
}
function drawOri (ctx,pointA,pointB,pointC,count) {
if (count>2) {
drawLine(ctx,pointA,pointB,pointC);
var t_A = getMiddlePoint(pointA,pointB);
var t_B = getMiddlePoint(pointA,pointC);
var t_C = getMiddlePoint(pointB,pointC);
count -= 1;
drawOri(ctx,t_A,pointB,t_C,count);
drawOri(ctx,t_A,t_B,pointA,count);
drawOri(ctx,pointC,t_B,t_C,count);
} else if(count==2){
drawLine(ctx,pointA,pointB,pointC);
var t_A = getMiddlePoint(pointA,pointB);
var t_B = getMiddlePoint(pointA,pointC);
var t_C = getMiddlePoint(pointB,pointC);
count -= 1;
drawOri(ctx,t_A,t_B,t_C,count);
}else{
drawLine(ctx,pointA,pointB,pointC);
}
}
window.onload=function () {
var cav = document.getElementById(‘cav‘);
var ctx = cav.getContext(‘2d‘);
ctx.strokeStyle="#3333ff";
drawOri(ctx,new point(230,10),new point(10,450),new point(480,450),7);
var btn = document.getElementById(‘btn‘);
var val = 0;
btn.onclick=function () {
val = document.getElementById(‘Count‘).value;
if (parseInt(val).toString()!=‘NaN‘) {
ctx.clearRect(0,0,500,500);
drawOri(ctx,new point(230,10),new point(10,450),new point(480,450),val);
} else{
alert(‘error number‘);
};
}
}
</script>
</head>
<body style=‘margin:0 auto;width:800px;‘>
<div>
<input type=‘text‘ id=‘Count‘/><input type=‘button‘ value=‘运行‘ id=‘btn‘ />
</div>
<canvas id=‘cav‘ width=‘500‘ height=‘500‘ style=‘border:1px solid black;‘></canvas>
</body>
</html>编后语:
可能实现方式上算法不是最好的,大家如果有更好的js实现技巧,欢迎交流指导!
原文:http://www.cnblogs.com/szfBlogs/p/4896334.html