蓝森林首页 | 返回主页 | 本站地图 | 站内搜索 | 联系信箱 |
 您目前的位置:首页 > 自由软件 > 技术交流 > 应用编程


    

蓝森林 http://www.lslnet.com 2006年8月25日 8:28

Js在页面画一个圆的思考

基于上一篇日志(http://redhacker.blueidea.com/archives/2006/1342.shtml)的思考,我试图用js在页面画了一个圆,当然js好象有自己的图形类库(我只见过,用js做星际争霸的游戏,还有在csdn见过用js画圆,好象是js自带的图形函数库)。
原理:
1.数学中圆坐标为:(x-x0)^2+(y-y0)^2=r^2这个公式,其中(x0,y0)为圆心坐标,x,y为变量和自变量。
2.在网页中<div>标签在页面中的位置具有坐标的概念。
代码运行:
[html]
<script>
//code by redhacker
function drawCircle(r){
        var x0 = screen.width/2;//圆心纵坐标
        var y0 = screen.height/2;//圆心横坐标
        var r0 = Number(r);//半径
        var x1 = x0-r0;
        var x2 = x0+r0;
        var x,y;
        document.write("<div style=\"position:absolute;left:"+ x0 +"px;top:500px;color: #FF0000\"><h2>Draw Circle Demo</h2></div>");
        for(var i=x1;i<=x2;i++){
                x = i;
                y = Math.sqrt(Math.pow(r0,2) - Math.pow(x - x0,2)) + y0;
                document.write("<div style=\"position:absolute;left:"+ x +"px;top:"+ y +"px;color: #FF0000\">.</div>");
        }
        for(var i=x2;i>=x1;i--){
                x = i;
                y = -Math.sqrt(Math.pow(r0,2) - Math.pow(x - x0,2)) + y0;
                document.write("<div style=\"position:absolute;left:"+ x +"px;top:"+ y +"px;color: #FF0000\">.</div>");
        }
}
</script>
<input name="radii" type="text" id="radii" value="100" size="10" />
<input type="submit" name="Submit" value="画圆" onclick="drawCircle(document.getElementById('radii').value)"/>
[/html]
思考:
1.使用三角函数作为变量,则可以画出非常均匀的圆来,回头做,你也试试?;-)
2.使用勾股定理画个三角形行的通吗?

原文地址:http://redhacker.blueidea.com/archives/2006/1346.shtml

js画几何图形我以前也捣鼓过,还整出过一个画图板,简单的几何图形、直线、曲线、填充等功能也都有,大致思路是用表格,分割成很小的单元格,这些单元格就是基本的像素,画画线条还好,但是大面积填充不规则几何图形的时候,用了递归,所以经常造成堆栈溢出。总的来说,用js做图形意义不大,js本身的效率再加上web端缓慢的渲染,那是很无趣的尝试。至于所谓的js图形类库,好像没见过。

搜了一下,竟然还能找到最初的一些东西。
[html]
<html>
<head>
</head>
<body style="cursor:hand">
<br/><br/>
<table align="center">
    <tr>
        <td align="center">

            <input type="button" value="点" onclick="draw_Type='Point';firstP_R=firstP_C=secondP_R=secondP_C=-1;window.viewsource.value='点'">
            <input type="button" value="线段" onclick="draw_Type='Line';firstP_R=firstP_C=secondP_R=secondP_C=-1;window.viewsource.value='线段'">
            <input type="button" value="连续线段" onclick="draw_Type='c_Line';firstP_R=firstP_C=secondP_R=secondP_C=-1;window.viewsource.value='连续线段'">
            <input type="button" value="圆" onclick="draw_Type='Circle';firstP_R=firstP_C=secondP_R=secondP_C=-1;window.viewsource.value='圆'">
            <select onchange="default_Color=this.value">
                <option value="green">绿色</option>
                <option value="black">黑色</option>
                <option value="red">红色</option>
                <option value="blue">兰色</option>
                <option value="yellow">黄色</option>
            </select>
        </td>
    </tr>
</table>
<script language="javascript">
var draw_Type = "Line";
var firstP_R=firstP_C=secondP_R=secondP_C=-1;
var distance;
var r_Index,c_Index;
var srcE;
var default_Color = "green";

function main_F(){
    srcE = event.srcElement;
    if(srcE.type != "button" && srcE.type != "select-one" && srcE.type != "text"){
        if(firstP_R == -1){
            firstP_R = event.x;
            firstP_C = event.y;
            draw_Point(firstP_R,firstP_C,default_Color);
            return false;
        }else{
            secondP_R = event.x;
            secondP_C = event.y;
            draw_Point(secondP_R,secondP_C,default_Color);
            distance = Math.sqrt((firstP_R-secondP_R)*(firstP_R-secondP_R)+(firstP_C-secondP_C)*(firstP_C-secondP_C));
        }
    }else{
        return false;
    }
    if(draw_Type == "Point"){
        draw_Point(event.x,event.y,default_Color);
    }else if(draw_Type == "Circle"){
        //画圆
        draw_Circle();
        firstP_R=firstP_C=secondP_R=secondP_C=-1;
    }else if(draw_Type == "Line"){
        //画单根直线
        draw_Line();
        firstP_R=firstP_C=secondP_R=secondP_C=-1;
    }else if(draw_Type == "c_Line"){
        //画连续直线
        draw_Line();
        firstP_R = secondP_R;
        firstP_C = secondP_C;
        secondP_R=secondP_C=-1;
    }else if(draw_Type == ""){
        window.viewsource.value="请重新选择操作!!!!!!!!!";
    }
}

function draw_Point(x,y,color){
    var newObj=document.createElement("IMG");
    document.body.appendChild(newObj);
    with(newObj){
        border=0;
        style.position='absolute';
        style.pixelLeft=(x);
        style.pixelTop=(y);
        style.backgroundColor=color;
        style.pixelWidth=1;
        style.pixelHeight=1;
    }
}

function draw_Line(){
    r_Index = (firstP_R-secondP_R)/distance;
    c_Index = (firstP_C-secondP_C)/distance;

    for(var i=0;i<distance;i++){
        draw_Point(firstP_R-=r_Index,firstP_C-=c_Index,default_Color);
    }
}

function draw_Circle(){
    //for循环里的步距和步长有待选择更优化的算法和数值
    r_Index = c_Index = 1/distance;

    for(var i=0;i<=6.2832;i+=r_Index){
        exc_x=Math.sin(i)*distance;
        exc_y=Math.cos(i)*distance;
        draw_Point(firstP_R+exc_x,firstP_C+exc_y,default_Color);
    }
}

function move_F(){
    if(event.button==1){
        window.viewsource.value="任意线形";
        draw_Type="";
        draw_Point(event.clientX,event.clientY,default_Color);
    }
   
    return false;
}
document.onclick = main_F;
//document.onmousemove = move_F;

</script>
<br><br><br><br>
<textarea name="viewsource" readonly rows="10" cols="80">线段</textarea>

</body>
</html>

[/html]

其实很久以前我就问过这个问题,我佛山人做过答,刚找了一下找到了,是用三角函数写的
http://bbs.blueidea.com/viewthread.php?tid=1181877

[html]
<script>
//code by redhacker
function drawCircle(r){
  var x0 = screen.width/2;//圆心纵坐标
  var y0 = screen.height/2;//圆心横坐标
  var r0 = Number(r);//半径
  var angle = 2*Math.PI/1000
  var x,y;
  var i=0
  document.write("<div style=\"position:absolute;left:"+ x0 +"px;top:500px;color: #FF0000\"><h2>Draw Circle Demo</h2></div>");
  while(i<=2*Math.PI){
  x = x0 + r0*Math.cos(i);
  y = x0 + r0*Math.sin(i);
  document.write("<div style=\"position:absolute;left:"+ x +"px;top:"+ y +"px;color: #FF0000\">.</div>");
i = i+angle;
  }
}
</script>
<input name="radii" type="text" id="radii" value="100" size="10" />
<input type="submit" name="Submit" value="画圆" onclick="drawCircle(document.getElementById('radii').value)"/>
[/html]

楼上的算法无论从精确程度还是效率上都......
现改进如下:
[html]
<script>
var points=new Array();
//code by redhacker
//edited by shouhaimu
function drawCircle(r){
  var x0 = screen.width/2;//圆心纵坐标
  var y0 = screen.height/2;//圆心横坐标
  var c0 = 2*Math.PI*r;
  var x,y;
  var i=0
  document.write("<div style=\"position:absolute;left:"+ x0 +"px;top:500px;color: #FF0000\"><h2>Draw Circle Demo</h2></div>");
  while(i<=c0){
    x = Math.round(x0 + r*Math.cos(i/r));
    y = Math.round(x0 + r*Math.sin(i/r));
    points[i]="<div style=\"position:absolute;left:"+ x +"px;top:"+ y +"px;color: #FF0000\">.</div>";
    i = i+1;
  }
  document.write(points.join(''));
}
</script>
<input name="radii" type="text" id="radii" value="100" size="10" />
<input type="submit" name="Submit" value="画圆" onclick="drawCircle(document.getElementById('radii').value)"/>
[/html]

bjhaoyun在上个帖子中说

的确精确不少:D




Copyright © 1999-2000 LSLNET.COM. All rights reserved. 蓝森林网站 版权所有。 E-mail : webmaster@lslnet.com