Bresenham提出的直线生成算法的基本原理是,每次在最大位移方向上走一步,而另一个方向是走步还是不走步取决于误差项的判别,具体的实现过程大家可以去问度娘。我主要是利用canvas画布技术实现了这个过程,算法可能还是有点小问题,欢迎大家给我留言建议,一定虚心接受。

    <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中点Bresenham算法</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei UI", "Microsoft YaHei", SimHei, "\5B8B\4F53", simsun, sans-serif;
color: #555;
}
.left {
float: left;
margin: 20px 0 0 calc((100% - 401px - 602px)/2);
width: 400px;
height: 600px;
border: 1px solid #cccccc;
border-right: none;
}
.left header {
margin: 0 10px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
height: 60px;
line-height: 60px;
font-size: 18px;
/*text-align: center;*/
border-bottom: 2px solid #aaa;
}
.start {
margin: 0 25px;
line-height: 80px;
/*text-align: center;*/
}
.left input[type="text"] {
padding: 2px 5px;
width: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
background-color: #f5f5f5;
border: 1px solid #cccccc;
}
button {
border: none;
display: inline-block;
outline: 0;
padding: 6px 16px;
margin-bottom: 10px;
vertical-align: middle;
overflow: hidden;
text-decoration: none;
color: #fff;
background-color: #F88E8B;
text-align: center;
transition: .2s ease-out;
cursor: pointer;
white-space: nowrap;
box-shadow: 0px 1px 3px rgba(0,0,0,0.12), 0px 1px 2px rgba(0,0,0,0.24);
}
button:hover {
background-color: #F35F5C;
}
#stroke {
margin-left: 25px;
}
#reset {
margin-left: 10px;
}
/*.left button {
display: block;
margin: 0 auto;
}*/
#xy {
/*display: none;*/
}
.left p {
line-height: 40px;
text-align: center;
}
.table {
position: relative;
padding-top: 30px;
max-height: 373px;
overflow-y: auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#thead {
position: absolute;
z-index: 999;
width: 370px;
margin-left: 10px;
}
.left table {
margin: 0 0 10px 10px;
width: 370px;
border-collapse:collapse;
}
.left table th{
width: 33.3333%;
height: 30px;
border: 1px solid #cccccc;
background-color: #f1f1f1;
}
.left table td{
width: 33.3333%;
height: 30px;
text-align: center;
border: 1px solid #cccccc;
}
#myCanvas {
display: block;
float: left;
margin-top: 20px;
background-color: #fffdf6;
border: 1px solid #cccccc;
}
</style>
</head>
<body>
<div class="left" id="left">
<header>&nbsp;&nbsp;中点 <strong>Bresenham</strong> 算法</header>
<div class="start">
直线方程 :
<input type="text" id="A" required autocomplete="off"> x + <input type="text" id="B" required autocomplete="off"> y + <input type="text" id="C" required autocomplete="off"> = 0
</div>
<button id="stroke">开始绘制</button>
<button id="reset">重置</button> <div id="xy" style="display: none;">
<p><strong>坐标值</strong></p>
<table id="thead">
<tr>
<th> X </th>
<th> Y </th>
<th> d </th>
</tr>
</table>
<div class="table">
<table id="table">
<!-- <tr>
<th> X </th>
<th> Y </th>
<th> d </th>
</tr> -->
</table>
</div>
</div> </div>
<canvas id="myCanvas" width="600" height="600">
您的浏览器不支持canvas,请升级浏览器!
</canvas> <script> //*-----------------canvas画坐标表格---------------------*
var canvas=document.getElementById("myCanvas");
var context=canvas.getContext("2d"); function drowAxes() {
// 描绘边框
var grid_cols = 20;
var grid_rows = 20;
var cell_height = canvas.height / grid_rows;
var cell_width = canvas.width / grid_cols;
context.lineWidth = 1;
context.strokeStyle = "#cccccc"; // 结束边框描绘
context.beginPath();
// 准备画横线
for (var col = 1; col <= grid_cols; col++) {
var x = col * cell_width;
if(col == 10) {
context.beginPath();
context.strokeStyle = "#2FB9D6";
context.moveTo(x+0.5,0);
context.lineTo(x+0.5,canvas.height);
context.stroke();
}
else {
context.beginPath();
context.strokeStyle = "#cccccc";
context.moveTo(x+0.5,0);
context.lineTo(x+0.5,canvas.height);
context.stroke();
}
}
//准备画竖线
for(var row = 1; row <= grid_rows; row++){
var y = row * cell_height;
if(row == 10) {
context.beginPath();
context.strokeStyle = "#2FB9D6";
context.moveTo(0,y+0.5);
context.lineTo(canvas.width, y+0.5);
context.stroke();
}
else {
context.beginPath();
context.strokeStyle = "#cccccc";
context.moveTo(0,y+0.5);
context.lineTo(canvas.width, y+0.5);
context.stroke();
}
}
context.stroke(); //给坐标轴加刻度
for(var i=0;i <= grid_cols;i++) {
var x = i * cell_width;
context.font="13px Arial";
context.fillStyle="#000";
context.fillText(-10+i,5 + x,315);
}
for(var i=0;i <= grid_rows;i++) {
var y = i * cell_height;
context.font="13px Arial";
context.fillStyle="#000";
context.fillText(10-i,305,15 + y);
}
} //坐标生成及Canvas画点函数
function drawDot(x,y,d) {
var tr=document.createElement("tr");
var td1=document.createElement("td");
var node1=document.createTextNode(" "+Math.round(x)+" ");
td1.appendChild(node1);
tr.appendChild(td1); var td2=document.createElement("td");
var node2=document.createTextNode(" "+Math.round(y)+" ");
td2.appendChild(node2);
tr.appendChild(td2); var td3=document.createElement("td");
var node3=document.createTextNode(" "+d.toFixed(2)+" ");
td3.appendChild(node3);
tr.appendChild(td3); document.getElementById("table").appendChild(tr); //坐标处理
var X,Y;
X= Math.round(x)*30;
Y=- Math.round(y)*30;
//表格中绘制坐标点
context.fillStyle="#2FB9D6";
context.beginPath();
context.arc(X,Y,4,0,Math.PI*2,true);
context.closePath();
context.fill();
} //判断输入的字符是否为整数
function IsInteger()
{
var str1 = document.getElementById('A').value.trim();
var str2 = document.getElementById('B').value.trim();
var str3 = document.getElementById('C').value.trim();
if(str1.length!=0 && str2.length!=0 && str3.length!=0){
reg=/^[-+]?\d*$/;
if(!reg.test(str1) || !reg.test(str2) || !reg.test(str3)){
alert("对不起,请输入整数!");//请将“整数类型”要换成你要验证的那个属性名称!
return false;
}
else {return true;}
}
} window.onload = drowAxes();
var canvas_flag=0;//设置是否画线的标记变量 //*-----------------中点Bresenham算法求坐标--------------------*
document.getElementById("stroke").onclick=function Bresenham(){
var xy=document.getElementById("xy"); var A=document.getElementById("A").value;
var B=document.getElementById("B").value;
var C=document.getElementById("C").value; if(A.length == 0 || B.length == 0 || C.length == 0) {alert("请填写直线方程的系数!")}
//直线上取两个点
if(xy.style.display === 'none' && A.length != 0 && B.length != 0 && C.length != 0 && IsInteger()) {
if(A==0 && B==0 && C!=0) {alert("输入错误,请重新输入!");}
else if(A==0 && B==0 && C==0) {alert("输入数据不能全部为0!")}
else if(A==0 && B!=0) { //y=c 类方程
context.translate(300,300);//将坐标原点移到(300,300)处 //绘制直线
var c=-Math.round(C/B)*30;
context.beginPath();
context.strokeStyle="#2FB9D6";
context.moveTo(-300,c);
context.lineTo(300,c);
context.closePath();
context.stroke(); canvas_flag=1;//标记变量置1 }
else if(A!=0 && B==0) { //x=c 类方程
context.translate(300,300);//将坐标原点移到(300,300)处 //绘制直线
var c=-Math.round(C/A)*30;
context.beginPath();
context.strokeStyle="#2FB9D6";
context.moveTo(c,-300);
context.lineTo(c,300);
context.closePath();
context.stroke(); canvas_flag=1;//标记变量置1 }
else if(-A/B>=0){ //斜率大于等于0的情况
xy.style.display = 'block';
var x0,y0,x1,y1;
var vx,vy;
var d; //增长量
var m,n; //循环变量
var x,y; var k = -A/B;
if(k>=0 && k<=1) { //k大于等于0小于等于1的情况
x0 = -5;x1 = 5;
y0 = (-C -A*x0)/B;
y1 = (-C -A*x1)/B;
vx = x1 - x0,vy = y1 - y0;
x = x0,y = y0;
n = x0;
m = x1;
d = vx - 2*vy; //初始化d
}
else if(k>1) { //k大于1的情况
y0 = -5;y1 = 5;
x0 = (-C -B*y0)/A;
x1 = (-C -B*y1)/A;
vx = x1 - x0,vy = y1 - y0;
x = x0,y = y0;
n = y0;
m = y1;
d = 2*vx - vy; //初始化d
}
context.translate(300,300);//将坐标原点移到(300,300)处
for(var i=n;i<=m;i++) { //----------------算法核心代码---------------
if(k>=0 && k<=1) { //k大于等于0小于等于1的情况
drawDot(x,y,d);
if(d<0) {
x = x + 1;
y = y + 1;
d = d + 2*vx - 2*vy;
}
else {
x = x + 1;
y = y;
d = d - 2*vy;
}
}
else if(k>1) { //k大于1的情况
drawDot(x,y,d);
if(d<0) {
x = x;
y = y + 1;
d = d + 2*vx;
}
else {
x = x + 1;
y = y + 1;
d = d - 2*vy + 2*vx;
}
} }
//绘制直线
var X0,Y0,X1,Y1;
X0= Math.round(x0)*30;
Y0=-Math.round(y0)*30;
X1=Math.round(x1)*30;
Y1=-Math.round(y1)*30;
context.beginPath();
context.strokeStyle="#2FB9D6";
context.moveTo(X0,Y0);
context.lineTo(X1,Y1);
context.closePath();
context.stroke(); canvas_flag=1;//标记变量置1
}
else if(-A/B<0){ //斜率小于0的情况
//将直线转化为斜率大于等于0的情况,然后求关于x轴对称的直线就行
xy.style.display = 'block';
A = -A;
var x0,y0,x1,y1;
var vx,vy;
var d; //增长量
var m,n; //循环变量
var x,y; var k = -A/B;
if(k>=0 && k<=1) { //k大于等于0小于等于1的情况
x0 = -5;x1 = 5;
y0 = (-C -A*x0)/B;
y1 = (-C -A*x1)/B;
vx = x1 - x0,vy = y1 - y0;
x = x0,y = y0;
n = x0;
m = x1;
d = vx - 2*vy; //初始化d
}
else if(k>1) { //k大于1的情况
y0 = -5;y1 = 5;
x0 = (-C -B*y0)/A;
x1 = (-C -B*y1)/A;
vx = x1 - x0,vy = y1 - y0;
x = x0,y = y0;
n = y0;
m = y1;
d = 2*vx - vy; //初始化d
}
context.translate(300,300);//将坐标原点移到(300,300)处
for(var i=n;i<=m;i++) { //----------------算法核心代码---------------
if(k>=0 && k<=1) { //k大于等于0小于等于1的情况
drawDot(-x,y,d);
if(d<0) {
x = x + 1;
y = y + 1;
d = d + 2*vx - 2*vy;
}
else {
x = x + 1;
y = y;
d = d - 2*vy;
}
}
else if(k>1) { //k大于1的情况
drawDot(-x,y,d);
if(d<0) {
x = x;
y = y + 1;
d = d + 2*vx;
}
else {
x = x + 1;
y = y + 1;
d = d - 2*vy + 2*vx;
}
} }
//绘制直线
var X0,Y0,X1,Y1;
X0= Math.round(-x0)*30;
Y0=-Math.round(y0)*30;
X1=Math.round(-x1)*30;
Y1=-Math.round(y1)*30;
context.beginPath();
context.strokeStyle="#2FB9D6";
context.moveTo(X0,Y0);
context.lineTo(X1,Y1);
context.closePath();
context.stroke(); canvas_flag=1;//标记变量置1
}
} }; //重新绘制
document.getElementById("reset").onclick=function reset(){ var A=document.getElementById("A").value;
var B=document.getElementById("B").value;
var C=document.getElementById("C").value;
if(A.length == 0 && B.length == 0 && C.length == 0) {alert("没有输入数据!")}
else {
//清空input输入框
document.getElementById("A").value="";
document.getElementById("B").value="";
document.getElementById("C").value="";
}
if(canvas_flag==1) {
context.clearRect(-300,-300,600,600); //清空画布
context.translate(-300,-300); //将坐标原点还原
drowAxes(); //重绘坐标轴 canvas_flag=0;
}
if(document.getElementById("xy").style.display === 'block') {
document.getElementById("xy").style.display = 'none'; var table = document.getElementById("table");
while(table.hasChildNodes()) //当table下还存在子节点时 循环继续
{
table.removeChild(table.firstChild);
}
}
}; </script>
</body>
</html>

利用canvas实现的中点Bresenham算法的更多相关文章

  1. 《图形学》实验七:中点Bresenham算法画椭圆

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画椭圆. 实验结果: 代码: #include <gl/glut.h> #define WIDTH 50 ...

  2. 《图形学》实验六:中点Bresenham算法画圆

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画圆. 实验结果: 代码: #include <gl/glut.h> #define WIDTH 500 ...

  3. 《图形学》实验四:中点Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h& ...

  4. Python使用DDA算法和中点Bresenham算法画直线

    title: "Python使用DDA算法和中点Bresenham算法画直线" date: 2018-06-11T19:28:02+08:00 tags: ["图形学&q ...

  5. [DEBUG]椭圆的中点Bresenham算法边缘绘制出现错误

    在使用椭圆的中点Bresenham算法绘制椭圆时, 当椭圆足够大时, 椭圆的边缘会出现下面这种情况. 出错原因: 将a, b声明为了int类型, 导致中点判别式中发生溢出 关注后面的a*b*a*b当a ...

  6. 《图形学》实验五:改进的Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用改进的Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h ...

  7. 直线的中点Bresenham算法的实现

    一.实验目的 1.掌握在MFC中搭建图形绘制的基本框架的方法: 2.将直线的中点Bresenham算法转化成可执行代码. 二.实验内容 1. 通过分析具体数据在中点Bresenham算法上的执行过程, ...

  8. Bresenham算法画填充圆及SDL代码实现

    画圆是计算机图形操作中一个非常重要的需求.普通的画圆算法需要大量的浮点数参与运算,而众所周知,浮点数的运算速度远低于整形数.而最终屏幕上影射的像素的坐标均为整形,不可能是连续的线,所以浮点数运算其实纯 ...

  9. 基于Bresenham算法画圆

    bresenham算法画圆思想与上篇 bresenham算法画线段 思想是一致的 画圆x^2+y^2=R^2 将他分为8个部分,如上图 1. 只要画出1中1/8圆的圆周,剩下的就可以通过对称关系画出这 ...

随机推荐

  1. EINTR、ERESTARTSYS和SIGINT

    1. 驱动使用down_interruptible,并在该函数返回非零值时返回-EINTR:应用程序不处理signal,使用CTRL-C退出应用程序: 驱动从down_interruptible返回, ...

  2. bzoj3035: 导弹防御塔

    Description Freda的城堡——“Freda,城堡外发现了一些入侵者!”“喵...刚刚探究完了城堡建设的方案数,我要歇一会儿嘛lala~”“可是入侵者已经接近城堡了呀!”“别担心,rain ...

  3. Python 从sketch中读取文件

    =============================== RESTART: Shell =============================== >>> import o ...

  4. windows mobile 共享PC网络(win7)

    win7系统安装windows mobile,将设备插入底座后,设备并不能直接共享pc的网络直接上网.原来,当插入底座后,需要打开mobile设备中心,切换一下连接网络,或者打开此窗体后确定一下,即可 ...

  5. 127 Word Ladder

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  6. What is a Windows USB device path and how is it formatted?

    http://community.silabs.com/t5/Interface-Knowledge-Base/Windows-USB-Device-Path/ta-p/114059 Windows ...

  7. The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved

    偶在页面里引入了标签如下:     <%@   taglib   prefix="c"   uri="http://java.sun.com/jstl/core&q ...

  8. [HTMLDOM]删除已有的 HTML 元素

    摘自www.w3school.com:http://www.w3school.com.cn/htmldom/dom_elements.asp如需删除 HTML 元素,您必须清楚该元素的父元素: < ...

  9. SOA_环境安装系列3_Oracle Weblogic安装和环境搭建(案例)

    2014-01-03 Created By BaoXinjian

  10. BIP_开发案例03_将原有Report Builer报表全部转为XML Publisher形式(案例)

    2014-05-31 Created By BaoXinjian