雪原xy 发表于 2019-3-22 16:10:43

一个画多边形并求多边形面积的小练习

早上看到一个帖子,是求多边形面积的方法,感觉很独特,于是依照该方法做了一个;
//文档类
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=;
                var s:PolygonArea=new PolygonArea(ar);
                var dr:DrawPolygon=new DrawPolygon(ar);
                var txt:TextField=new TextField()
                public functiondoc():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 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 is Point&&re is Point){
//计算梯形面积,并赋值;
_area +=reckonArea(re.x,re.y,re.x,re.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 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 as Point).x,(arra 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 is Point){
this.graphics.lineTo(arra.x,arra.y);
}
}
//结束填充;
this.graphics.endFill();
}
}
}



attach://2215.swf

雪原xy 发表于 2019-3-22 16:30:16

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

TKCB 发表于 2019-3-23 19:02:01

【11RIA 闪客社区,评分公示】:
是否有价值:一般(银子 +10贡献 +1)
是否原创:是(金子 +1)
是否翻译:否
如对自己的评分有疑问,则咨询版主、管理员等。

qiuhao 发表于 2019-3-25 18:32:38

学习了,通过将多边形分成一个个梯形,根据多边形的顶点坐标求多边形的面积,这个方法我怎么想不到呢?画多边形的类中,为了封闭图形特意声明一个变量k,感觉没必要,因为endFill()方法就有封闭图形的作用

qiuhao 发表于 2019-3-26 12:07:50

另外,我试了(20,10)(80,20)(70,50)(30,60)(40,30)这组数,画图没问题,但是求得的面积是负数{:1_112:}

雪原xy 发表于 2019-3-26 12:18:22

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

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

雪原xy 发表于 2019-3-26 12:19:29

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

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

qiuhao 发表于 2019-3-29 11:18:04

雪原xy 发表于 2019-3-26 12:19
是吗?看来代码有问题,要查查!感谢回复!

我是跟着你后面学习#;P

Aone 发表于 2019-4-2 13:14:38

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

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

只提供一下思路,具体代码自己写吧。#:lol
AS3里BitmapData和ByteArray类是最好玩的两个类。祝你们玩的愉快#:lol
页: [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)