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. Python基础教程【读书笔记】 - 2016/7/24

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第九波:第9章  魔法方法.属性和迭代器  在Python中,有的名称会在前面和后面都加上两个下划线,这种写法很特别.已 ...

  2. 如何解决WebkitBrowser使用出错“Failed to initialize activation context”

    本文转载自:http://www.cnblogs.com/supjia/p/4695671.html 本篇文章主要介绍了"如何解决WebkitBrowser使用出错“Failed to in ...

  3. Nexus手动更新索引

    如果有耐心的话,完全可以通过在线更新索引的方式来做,但所消耗的时间较长,下面介绍一种简单.可行的方式来手动更新索引文件. 访问http://repo.maven.apache.org/maven2/. ...

  4. 51nod1369 无穷印章

    有一个印章,其完全由线段构成.这些线段的线足够细可以忽略其宽度,就像数学上对线的定义一样,它们没有面积.现在给你一张巨大的白纸(10亿x10亿大小的纸,虽然这个纸很大,但是它的面积毕竟还是有限的),你 ...

  5. android学习笔记39——使用原始资源

    原始资源 android中没有专门提供管理支持的类型文件,都被称为原始资源.例如:声音资源... android原始资源存放位置: 1.res/raw,android SDK会处理该目录下的原始资源, ...

  6. cowboy使用restful的例子

    直接贴代码,一切尽在不言中 %% cowboy的restful的文档,一定要好好阅读http://ninenines.eu/docs/en/cowboy/HEAD/manual/cowboy_rest ...

  7. Smartclient发布的几个异常问题

    1.不能下载.config文件 如果是iis6右键网站属性--->主目录--->配置 1.右键虚拟目录,在虚拟目录-配置-映射,应用程序扩展中删除.config 项目 2.IIS属性--& ...

  8. [工具开发] Perl 爬虫脚本--从美国国家漏洞数据库抓取实时信息

    一.简介 美国国家漏洞数据库收集了操作系统,应用软件的大量漏洞信息,当有新的漏洞出现时,它也会及时发布出来. 由于信息量巨大,用户每次都需要到它的网站进行搜索,比较麻烦.如果能有个工具,每天自动分析它 ...

  9. DBA_Oracle海量数据处理分析(方法论)

    2014-12-18 Created By BaoXinjian

  10. 牢骚 - 你代码写得丑,又不肯用好一点的IDE,这让我很为难啊。

    又有人问我代码错误,发过来就是一篇巨丑无比的代码,先不说左大括号转行还和代码写在同一行的谭浩强风格,你这狗啃的一样的缩进是闹哪样!粘进VS2015里面,自动格式化,瞬间赏心悦目,编译错误出了5行,我直 ...