三角形填充算法

三角形填充算法

这个算法的精妙之处在于把求斜率的部分改为了插值计算,解决了浮点数的问题。整个部分并没有直接去求直线的斜率。
能用代码解释的尽量不BB,见代码:

private function drawTriangleEasy(p1:Point, p2:Point, p3:Point, color:uint = 0):void
		{
			//1. 按y值排序 p1.y ≤ p2.y ≤ p3.y 
			var temp:Point;
			//p1.y < p2.y
			if(p1.y > p2.y)
			{
				temp = p1;
				p1 = p2;
				p2 = temp;
			}
			//p1.y < p3.y
			if(p1.y > p3.y)
			{
				temp = p1;
				p1 = p3;
				p3 = temp;
			}
			//p2.y < p3.y
			if(p2.y > p3.y)
			{
				temp = p2;
				p2 = p3;
				p3 = temp;
			}
			trace(p1, p2, p3);
			this.pointContianer.graphics.beginFill(0xff0000, 1);
			this.pointContianer.graphics.drawCircle(p1.x, p1.y, 2);
			this.pointContianer.graphics.drawCircle(p2.x, p2.y, 2);
			this.pointContianer.graphics.drawCircle(p3.x, p3.y, 2);
			this.pointContianer.graphics.endFill();
			//2.判断p2在p1p3的那一侧, 只比较x值是不够的
			//可以用直线的一般方程来判断, <0 在左侧, >0在右侧. 可用 y-x=0  y-2x=0  y-0.5x=0 这三条直线来检测
			//已知两点可求得直线的一般方程式, AX + BY + C = 0, (x1, y1), (x2, y2) 先用斜截式考虑飞0情况展开, 再考虑0的情况, 可求得
			// A = Y2 - Y1,  B = X1 - X2, C = X2*Y1 - X1*Y2
			// p1 => (x1, y1) , p3 => (x2, y2) 因为斜率是按照 p1计算的
			var a:Number = p3.y - p1.y;
			var b:Number = p1.x - p3.x;
			var c:Number = p3.x*p1.y - p1.x*p3.y;
			var result:Number = p2.x*a + p2.y*b + c;
			
			if(result > 0)
			{
				trace("p2 at right of p1p3");
				for(y = (p1.y >> 0) ; y <= (p3.y >> 0); y++)
				{
					if(y < p2.y)
					{
						this.processScanLine(y, p1, p3, p1, p2, color);
					}else
					{
						this.processScanLine(y, p1, p3, p2, p3, color);//平顶 如果 p1.y == p2.y 直接就处理这里了, 精妙!
					}
				}
			}else
			{
				trace("p2 at left of p1p3");
				for(y = (p1.y >> 0) ; y <= (p3.y >> 0); y++)
				{
					if(y < p2.y)
					{
						this.processScanLine(y, p1, p2, p1, p3, color);
					}else
					{
						this.processScanLine(y, p2, p3, p1, p3, color);
					}
				}
			}
		}
private function processScanLine(y:int, pa:Point, pb:Point, pc:Point, pd:Point, color:uint = 0):void
		{
	
			var gradient1:Number = pa.y != pb.y ? (y - pa.y) / (pb.y - pa.y) : 1;
			var gradient2:Number = pc.y != pd.y ? (y - pc.y) / (pd.y - pc.y) : 1;
			
			var sx:int = this.interpolate(pa.x, pb.x, gradient1) >> 0;
			var ex:int = this.interpolate(pc.x, pd.x, gradient2) >> 0;
			
			// drawing a line from left (sx) to right (ex) 
			for(var x:int = sx; x < ex; x++) {
				this.bmd.setPixel(x, y, color);
			}
		}
		
		private function interpolate(p0:Number, p1:Number, gradient:Number):Number
		{
			return p0 + (p1 - p0)* this.clamp(gradient);
		}
		
		private function clamp(value:Number, min:Number = 0, max:Number = 1):Number
		{
			return Math.max(min, Math.min(value, max));
		}

三角形填充算法_第1张图片

你可能感兴趣的:(计算几何)