代码功能是随机生成一系列的多边形,计算各多边形的面积并显示,并且能给各多边形染色。
使用语言: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>