11RIA 闪客社区 - 最赞 Animate Flash 论坛

搜索
查看: 2916|回复: 8
上一主题 下一主题

[Shape 形状] 一个画多边形并求多边形面积的小练习

[复制链接] TA的其它主题
发表于 2019-3-22 16:10:43 | 显示全部楼层 |阅读模式

【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
早上看到一个帖子,是求多边形面积的方法,感觉很独特,于是依照该方法做了一个;
[Actionscript3] 纯文本查看 复制代码
//文档类
package  {
	
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.text.TextField;

	public class doc extends Sprite {
		var p1:Point=new Point(15,15);
		var p2:Point=new Point(50,55);
		var p3:Point=new Point(55,15);
		var p4:Point=new Point(40,0);
		var ar:Array=[p1,p2,p3,p4];
		var s:PolygonArea=new PolygonArea(ar);
		var dr:DrawPolygon=new DrawPolygon(ar);
		var txt:TextField=new TextField()
		public function  doc():void{
		trace("这个多边形的面积为:"+s.area);
		addChild(dr);
		txt.autoSize="left";
		txt.text="这个多边形的面积为:";
		txt.appendText(String(s.area));
		txt.x=dr.x+10;
		txt.y=dr.y+dr.height+5
		addChild(txt);
		}
	}
	}
	
//一个求多边形面积的类;
package {	
//需要用到多边形各个顶点的坐标;
import flash.geom.Point;	
//类名为多边形面积;
public class PolygonArea	{	
//定义一个私有属性,面积,后面用getter方法公开;
private var _area:Number=0;		
//构造函数中有一个数组参数,用来存放多边形的各个顶点,要按顺序排列;
public function PolygonArea(rest:Array):void		{		
//初始化方法;
	init(rest);		
	}	
//初始化方法里要先检查数组中的成员是不是点类型;
private function init(pa:Array):void	{	
//用一个布尔值来表示所有成员都是点类型!
var b:Boolean=true;		
//借助for循环来检查数组的成员;
for (var i:int = 0; i < pa.length; i++)		{			
//有一个不是点类型就退出,终止程序;
if (!( pa[i] is Point))			{				
trace("你输入的参数不全是点类型,请检查:第" + i + "个参数!!");				
b=false;				
break;			
}		
}		
//如果都是点类型,开始计算;
if(b){areaF(pa);
}
}
//计算多边形面积的方法;
private function areaF(re:Array):void{
//定义一个整数k,用来把末尾的计算回到起点;
var k:int;
//借助for循环来计算每一个梯形的面积,并相加;
for (var j:int = 0; j < re.length; j++){
//用if语句判断是否到末尾
if (j < re.length - 1){	
k = j;
}
//如果到了末尾,k+1指向起点;
else{	k =-1;}
//先要检验数组成员是否为点类型;
if(re[j] is Point&&re[k + 1] is Point){
//计算梯形面积,并赋值;
_area +=  reckonArea(re[j].x,re[j].y,re[k+1].x,re[k+1].y);
//把计算出来的面积输出,方便调试;
trace(_area)
}
}
}
//下面是计算梯形面积的方法,四个参数分别是第一个点的横坐标和纵坐标,第二个点的横坐标和纵坐标;
private function reckonArea(p1x:Number,p1y:Number,p2x:Number,p2y:Number):Number{
//定义一个存储面积的变量;
var _arN:Number;
//上底;
var a:Number = p1y;
//下底
var b:Number = p2y;
//高;
var h:Number =p2x-p1x;
//面积=(上底+下底)*高÷2;
_arN = (a + b) * h / 2;
//把面积返回;
return _arN;
}
//设置getter方法,公开面积属性;
public function get area():Number{
	return _area;
}
}
}

//一个画多边形的类;
package{
//导入Point类;
import flash.geom.Point;
//导入Shape类,用来画图;
import flash.display.Shape;
//类名为画多边形,继承于Shape;
public class DrawPolygon extends Shape{
//传递一个数组,成员为多边形的顶点;
public function DrawPolygon(arr:Array):void{
//初始化方法;
init(arr);
}
//初始化方法里要先检查数组中的成员是不是点类型;
private function init(pa:Array):void	{	
//用一个布尔值来表示所有成员都是点类型!
var b:Boolean=true;		
//借助for循环来检查数组的成员;
for (var i:int = 0; i < pa.length; i++)		{			
//有一个不是点类型就退出,终止程序;
if (!( pa[i] is Point))			{				
trace("你输入的参数不全是点类型,请检查:第" + i + "个参数!!");				
b=false;				
break;			
}		
}		
//如果参数数组中都是点类型的成员,开始画图;
if(b){drawF(pa);}
}
//画图方法,有一个成员都是点类型的数组参数;
private function drawF(arra:Array):void{
//设置线条类型;
this.graphics.lineStyle(3,0xff0000);
//设置填充颜色;
this.graphics.beginFill(0x009900);
//设置起始点;
this.graphics.moveTo((arra[0] as Point).x,(arra[0] as Point).y);
//定义一个变量,在循环中把终点指向起始点,做出封闭的多边形;
var k:int;
//借助for循环来画图;
for(var j:int=0;j<arra.length;j++){
//用if…else语句来设置变量k的值;
if(j<arra.length-1){k=j;}
else{k=-1;}
//先判断成员是不是点类型,再画图;
if(arra[k+1] is Point){
this.graphics.lineTo(arra[k+1].x,arra[k+1].y);
}
}
//结束填充;
this.graphics.endFill();
}
}
}



评分

参与人数 1银子 +10 金子 +1 贡献 +1 收起 理由
TKCB + 10 + 1 + 1

查看全部评分

 楼主| 发表于 2019-3-22 16:30:16 | 显示全部楼层
学习总结:
1、这个方法必须要找到多边形各个顶点,根据顶点来求面积;
2、各顶点必须按顺序排列,顺序不同面积也会不同;
困惑:
1代码有点乱,方法不够优化,特别是参数的传递!
本想传递任意参数,但后面的计算无法进行,老是出现空对象的错误;
2,、很想再做一个可以根据鼠标点击来构造多边形的方法来实现;苦于没有好的思路!
回复

使用道具 举报

发表于 2019-3-23 19:02:01 | 显示全部楼层
【11RIA 闪客社区,评分公示】:
是否有价值:一般(银子 +10  贡献 +1)
是否原创:是(金子 +1)
是否翻译:否
如对自己的评分有疑问,则咨询版主、管理员等。
回复

使用道具 举报

发表于 2019-3-25 18:32:38 | 显示全部楼层
学习了,通过将多边形分成一个个梯形,根据多边形的顶点坐标求多边形的面积,这个方法我怎么想不到呢?画多边形的类中,为了封闭图形特意声明一个变量k,感觉没必要,因为endFill()方法就有封闭图形的作用
回复

使用道具 举报

发表于 2019-3-26 12:07:50 | 显示全部楼层
另外,我试了(20,10)(80,20)(70,50)(30,60)(40,30)这组数,画图没问题,但是求得的面积是负数
回复

使用道具 举报

 楼主| 发表于 2019-3-26 12:18:22 | 显示全部楼层
qiuhao 发表于 2019-3-25 18:32
学习了,通过将多边形分成一个个梯形,根据多边形的顶点坐标求多边形的面积,这个方法我怎么想不到呢?画多 ...

哦,谢谢回复,不知道endFill()还有这功能!
回复

使用道具 举报

 楼主| 发表于 2019-3-26 12:19:29 | 显示全部楼层
qiuhao 发表于 2019-3-26 12:07
另外,我试了(20,10)(80,20)(70,50)(30,60)(40,30)这组数,画图没问题,但是求得的面积是负 ...

是吗?看来代码有问题,要查查!感谢回复!
回复

使用道具 举报

发表于 2019-3-29 11:18:04 | 显示全部楼层
雪原xy 发表于 2019-3-26 12:19
是吗?看来代码有问题,要查查!感谢回复!

我是跟着你后面学习
回复

使用道具 举报

发表于 2019-4-2 13:14:38 | 显示全部楼层
求图形面积可以有一个比较简单的方法实现。步骤如下:
1.shape里绘制一个任意图形。也就是要求面积的图形。
2.建立一个BitmapData对象大小和第一步的图像一样大。并且把背景设置为透明。
3.用BitmapData的draw()方法把shape绘制进去。
4.用BitmapData的threshold()方法做一次像素替换操作,被替换的像素目标为全透明对象也就是值为0的像素,替换成什么颜色随意。这样threshold()方法会最终返回一个有效替换的像素数量。那么BitmapData的宽乘以高再减去这个替换的像素数量就是shape所占的像素总数,结果比较逼近于面积。

数值可能跟纯数学的算法来比精度不够高,但是优势就是简单代码量极其少(可能不超过10行),而且可以计算不规则位图的面积。

只提供一下思路,具体代码自己写吧。
AS3里BitmapData和ByteArray类是最好玩的两个类。祝你们玩的愉快
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

感谢所有支持论坛的朋友:下面展示最新的5位赞助和充值的朋友……更多赞助和充值朋友的信息,请查看:永远的感谢名单

SGlW(66139)、 anghuo(841)、 whdsyes(255)、 longxia(60904)、 囫囵吞澡(58054)

下面展示总排行榜的前3名(T1-T3)和今年排行榜的前3名的朋友(C1-C3)……更多信息,请查看:总排行榜今年排行榜

T1. fhqu1462(969)、 T2. lwlpluto(14232)、 T3. 1367926921(962)  |  C1. anghuo(147)、 C2. fdisker(27945)、 C3. 囫囵吞澡(58054)



快速回复 返回顶部 返回列表