隨機生成一系列多邊形計算面積並染色

     代碼功能是隨機生成一系列的多邊形,計算各多邊形的面積並顯示,並且能給各多邊形染色。

     使用語言:html5與js

     算法有1、凸包算法(用於隨機生成多邊形) 2、多邊形計算面積算法(主要通過分解成三角形,通過各座標點計算三角形面積)

     缺陷:選中多邊形時,取了巧,僅選擇畫布代替了選擇多邊形。

   代碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無標題文檔</title>
<style type="text/css">
#area{
	width:80px;
}
p{
	text-align:center;
}
</style>
</head>

<body>
<script>
var k=0;                                  //面積數組key
var num=Math.floor(Math.random()*10)+8;   //num個多邊形
var sarea=new Array();                      //多邊形面積數組
var cxt=new Array();                           //筆刷數組
var numn=new Array();                           //多邊形邊數記錄數組
var ggdbxpoint=new Array(num);               //所有多邊形點數組(最終爲三維數組)
for(var j=0;j<38;j++)
 ggdbxpoint[j]=new Array();
for(var i=0;i<num;i++)
 {
	 document.write("<canvas id=\""+i+"\" width=\"200\" height=\"200\" οnclick=\"onclickchange(this);\">
Your browser does not support the canvas element.</canvas>");
	 var c=document.getElementById(""+i+"");                                                              //輸出num個畫布,初始化畫筆
	 cxt[i]=c.getContext("2d");
     cxt[i].beginPath();
 }
function point(px,py)
{
	this.x=px;
	this.y=py;                   //點結構
}
function ComputeTriangleArea(p1,p2,p3) {   
    return 0.5 * ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y));   //三角形的面積
}   
function ComputePolygonAreaTri(points,length) {   
    if (points==" "|| length <= 0) return 0;   
    p0=new point(points[0].x,points[0].y);   
   var area = 0;   
    for (var i = 0; i < length - 2; ++ i) {   
        area += ComputeTriangleArea(p0, points[i+1], points[i + 2]);   //多邊形的面積
    }   

    return area>0?area:-area;   
} 

function cmp(p1,p2)   //根據座標值將點從小到大排序
{
  return p1.y > p2.y || (p1.y == p2.y && p1.x > p2.x);
}
function ral(p1,p2,p3) //用叉乘判斷點的位置
{
    return ((p2.x - p1.x)*(p3.y - p1.y) > (p3.x - p1.x)*(p2.y - p1.y));
}
function drawpolygon(begin,end,count)                                       //畫多邊形
{
  var res=new Array();            //凸點數組
  var p=new Array();                  //所有點數組
  var n=Math.floor(Math.random()*38)+3; //n邊形
  for(var i=0;i<n;i++)
  {
	  p[i]=new point(Math.floor(Math.random()*end)+begin,Math.floor(Math.random()*end)+begin);
	  res[i]=new point();
  }
  temp=new point();
  for(var i=0;i<p.length;i++)
	 for(var j=0;j<p.length-i-1;j++)
	   {
		   if(p[j].y > p[j+1].y || (p[j].y == p[j+1].y && p[j].x > p[j+1].x))
			  {
				  temp=p[j];
				  p[j]=p[j+1];
				  p[j+1]=temp;
			  }			
	   }
	res[0] = p[0];
	res[1] = p[1];
	var t = 1;
	for(i = 2; i < n; i++)
	{
		while(t && !ral(res[t],res[t - 1],p[i]))
			t--;                                              //計算凸包點
		res[++t] = p[i];
	}
   var len = t;
	res[++t] = p[n - 2];
	for(i = n - 3; i >= 0; i--)
	{
	  while(t != len && !ral(res[t],res[t - 1],p[i]))
		   t--;
	  res[++t] = p[i];
	}
	sarea[k++]=ComputePolygonAreaTri(res,t);                  //面積記錄數組
    numn[count]=t;
  for(var i=0;i<t;i++)
  {
	  ggdbxpoint[count][i]=res[i];
	  if(i==0)
	   cxt[count].moveTo(res[i].x,res[i].y);
	  else
	   cxt[count].lineTo(res[i].x,res[i].y);   //連接各凸包點   
	  if(i+1==t)
     {
		 cxt[count].lineTo(res[0].x,res[0].y);
         cxt[count].closePath();
	     cxt[count].fillStyle="white";
         cxt[count].fill();
         cxt[count].stroke();
	 }
 }
   
}
for(var begin=1,end=199,i=0;i<num;i++)
   {
	   drawpolygon(begin,end,i);                     //畫num個隨機多邊形
   }

  document.write("<p>多邊形:<select id=\"dbx\" name=\"dbx\">");
  for(var i=1;i<=num;i++)
    document.write("<option value=\""+i+"\" >"+i+"</option>");
  document.write("</select>");
  document.write("多邊形面積:<input id=\"area\" name=\"area\" type=\"button\" value=\"\">");
  document.write("多邊形顏色:red:<select id=\"red\" name=\"red\">");
  for(var i=0;i<256;i++)
    document.write("<option value=\""+i+"\" >"+i+"</option>");
  document.write("</select>");
    document.write("green:<select id=\"green\" name=\"green\">");                      //多邊形操作內容
  for(var i=0;i<256;i++)
    document.write("<option value=\""+i+"\" >"+i+"</option>");
  document.write("</select>");
    document.write("blue:<select id=\"blue\" name=\"blue\">");
  for(var i=0;i<256;i++)
    document.write("<option value=\""+i+"\" >"+i+"</option>");
  document.write("</select>");
    document.write("<input type=\"button\" value=\"確定\"  οnclick=\"changecolor();\"></p>");
function changecolor()
{                                                                              //對選中的多邊形進行操作
   var dbxid=document.getElementById("dbx");
   dbxid=dbxid.options[dbxid.selectedIndex].value;
   dbxid--;
   console.log(dbxid);
	document.getElementById("area").value=sarea[dbxid];
   cxt[dbxid].clearRect(0, 0, 200, 200);
   cxt[dbxid].beginPath();
   var r=document.getElementById("red");
   r=r.options[r.selectedIndex].value;
   var g=document.getElementById("green");
   g=g.options[g.selectedIndex].value;
   var b=document.getElementById("blue");
   b=b.options[b.selectedIndex].value;
      cxt[dbxid].fillStyle="rgb("+r+","+g+","+b+")";
	   cxt[dbxid].strokeStyle="rgb("+r+","+g+","+b+")";
  for(var i=0;i<numn[dbxid];i++)
  {
	 
	  if(i==0)
	   cxt[dbxid].moveTo( ggdbxpoint[dbxid][i].x, ggdbxpoint[dbxid][i].y);
	  else
	   cxt[dbxid].lineTo( ggdbxpoint[dbxid][i].x, ggdbxpoint[dbxid][i].y);   //連接各凸包點   
	  if(i+1==numn[dbxid])
     {
         cxt[dbxid].closePath();
         cxt[dbxid].fill();
         cxt[dbxid].stroke();
	 }
 }
}
changecolor();

function onclickchange(obj)
{
	var dbxid=obj.id;
	 console.log(dbxid);
    alert("已選中第"+(eval(dbxid)+1)+"多邊形!");                              //鼠標單擊多邊形時操作
	document.getElementById("dbx").value=eval(dbxid)+1;
	document.getElementById("area").value=sarea[dbxid];
	
}
</script>
</body>
</html>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章