Cocos2dx CrazyTetris 双线伪裁剪算面积 对于判断消除的思考(二)

上一篇主要讲了我对裁剪消除算法的思考,这一篇的主题是计算单行覆盖面积,以此来确定是否达到了裁剪条件。

就像之前所说的,在该游戏中,基本方块都由四个小方块构成,四个小方块的尺寸均是25*25。因此游戏区域是宽可容纳10个方块,高可容纳20个方块。即250*500。每行的间距均是25。

因此,现在的问题就是,如何判定在这个宽250,高25的区域内,方块所占的面积。如果能够计算出其面积,而这个区域的总面积为250 * 25 = 6250,那么就可以据此来判断是否满足消除条件。例如:面积 > 6000。

因此这里主要是讨论该套面积应当如何计算。

直接接上一篇。上一篇利用裁剪线将图形集合上下切割,而这里明显是要使用两条线,将图形进行上、中、下三片切割,然后根据切割结果计算中部的面积。如图:

其中红色区域就是要计算的面积。

这时,算法思想和单线裁剪还是很类似的。这里由于分了三层,因此三层编码需要两位:上层(01)、中层(00)、下层(10)。

然后根据该编码进行裁剪,只保存中部裁剪结果,然后利用裁剪结果(点集)创建PhysicsShapePolygon对象,并用其getArea()方法获取面积即可。

这其中,虽然进行了裁剪算法,但是并没有真正实施裁剪,因此叫做伪裁剪算法。

实现代码如下:

//计算面积算法
float BaseBlock::calculaArea(float y1, float y2)
{
	//定义上下多边形集
	float area = 0;

	//
	for(int i=0; i<shapeAmount; i++)
	{
		//
		std::vector<Vec2> * middleShape;

		middleShape = new std::vector<Vec2>();

		//逐边裁剪
		for(int j=0; j<shapeVecAmount->at(i); j++)
		{
			Vec2 startPoint = this->coordinateSpin(shapeVecs->at(i)[j]);
			Vec2 endPoint = this->coordinateSpin(shapeVecs->at(i)[(j+1)%shapeVecAmount->at(i)]);

			int cStart = 0;
			int cEnd = 0;

			//
			if((fabs(startPoint.y - y1) < 1e-6) && (fabs(endPoint.y - y1) < 1e-6))
			{
				cStart = cEnd = 0;
			}
			else if(fabs(startPoint.y - y1) < 1e-6)
			{
				if(endPoint.y - y1 < 1e-6)
				{
					cStart |= 2;
					cEnd |= 2;
				}
			}
			else if(fabs(endPoint.y - y1) < 1e-6)
			{
				if(startPoint.y - y1 < 1e-6)
				{
					cStart |= 2;
					cEnd |= 2;
				}
			}
			else
			{
				if(startPoint.y - y1 < 1e-6) cStart |= 2;
				if(endPoint.y - y1 < 1e-6) cEnd |= 2;
			}

			//
			if((fabs(startPoint.y - y2) < 1e-6) && (fabs(endPoint.y - y2) < 1e-6))
			{
				cStart = cEnd = 0;
			}
			else if(fabs(startPoint.y - y2) < 1e-6)
			{
				if(endPoint.y - y2 > 1e-6)
				{
					cStart |= 1;
					cEnd |= 1;
				}
			}
			else if(fabs(endPoint.y - y2) < 1e-6)
			{
				if(startPoint.y - y2 > 1e-6)
				{
					cStart |= 1;
					cEnd |= 1;
				}
			}
			else
			{
				if(startPoint.y - y2 > 1e-6) cStart |= 1;
				if(endPoint.y - y2 > 1e-6) cEnd |= 1;
			}

			if(cStart == cEnd)
			{
				//两顶点在同一边,无需裁剪
				if(cStart == 0)
				{
					//顶点在上边,记录到上边顶点集
					middleShape->push_back(coordinateGoBack(startPoint));
				}
			}
			else
			{
				//两顶点在不同边,需要进行裁剪
				if(cStart == 0)
				{
					float cutting_x;
					float cutting_y;
					if(cEnd == 1)
					{
						cutting_x = startPoint.x + (endPoint.x - startPoint.x) * (y2 - startPoint.y) / (endPoint.y - startPoint.y);
						cutting_y = y2;
					}
					else
					{
						cutting_x = startPoint.x + (endPoint.x - startPoint.x) * (y1 - startPoint.y) / (endPoint.y - startPoint.y);
						cutting_y = y1;
					}

					middleShape->push_back(coordinateGoBack(startPoint));
					middleShape->push_back(coordinateGoBack(Vec2(cutting_x, cutting_y)));
				}
				else
				{
					float cutting_x;
					float cutting_y;
					if(cStart == 1)
					{
						cutting_x = startPoint.x + (endPoint.x - startPoint.x) * (y2 - startPoint.y) / (endPoint.y - startPoint.y);
						cutting_y = y2;
					}
					else
					{
						cutting_x = startPoint.x + (endPoint.x - startPoint.x) * (y1 - startPoint.y) / (endPoint.y - startPoint.y);
						cutting_y = y1;
					}

					middleShape->push_back(coordinateGoBack(Vec2(cutting_x, cutting_y)));
				}

			}
		}

		Vec2 * middleTempShape = new Vec2[middleShape->size()];

		for(int index = 0; index < middleShape->size(); index++)
		{
			middleTempShape[index] = middleShape->at(index);
		}

		area += PhysicsShapePolygon::create(middleTempShape, middleShape->size())->getArea();
	}

	return area;
}

时间: 2024-09-30 20:04:10

Cocos2dx CrazyTetris 双线伪裁剪算面积 对于判断消除的思考(二)的相关文章

Cocos2dx3.2 CrazyTetris 单线裁剪 对于判断消除的思考(一)

由于不是规则的俄罗斯方块,在消除时,很可能产生不规则的图形,因此,如何判断是否达到消除条件,以及进行方块的裁剪将是本游戏的一个关键问题. 我在做这个游戏时,采用的是最直接的方法,也就是最笨的方法,直接进行裁剪判定.如果有比较好的算法,希望大家可以和我交流. 首先,接上一篇,由于我们创建的刚体模型,需要是凸多边形,因此,每个初始方块都由四个正方形小方块构成.如图: 而本游戏中,方块的旋转应该是任意的(而不是原版游戏中每次旋转都是90度).因此,当上面的方块停落时,很有可能是这样的方向: 因此,该方

cocos2dx[3.2](19)——裁剪节点ClippingNode

[唠叨] 学习cocos2dx 3.2确实比较吃力,因为网上关于最新版的v3.2的资料十分稀少,或者是讲解的确实不是很详细.大部分人都是根据官方文档照样画瓢,而对于有些比较抽象的概念及函数都是照着官方文档来讲解的.这样的结果,导致有些东西令我确实非常费解. 没有办法,只好自己来总结cocos2dx3.2,然后将个人的学习感悟分享给大家. PS:当然有些大牛写的文章还是很不错的. 有时候我们需要显示一张图片的部分区域,比如文字遮罩.图片遮罩... 本节要讲的ClippingNode的功能效果大致就

青岛理工ACM交流赛 J题 数格子算面积

数格子算面积 Time Limit: 1000MS Memory limit: 262144K 题目描述 给你一个多边形(用’\’和’/’表示多边形的边),求多边形的面积. 输入 第一行两个正整数h 和 w (2 ≤ h, w ≤ 100),h是多边形所在平面的高,w是多边形所在平面的宽,接下来h行,每行w个字符,描述了整个平面的每个单元(每个单元是一个单位面积),字符只会是’\’,’/’和’.’其中之一,’\’,’/’表示多边形的边,’.’表示空白单元. 输出 输出一个数,输入代表的平面内多边

cocos2d-x新手引导遮罩CCClippingNode裁剪区域

废话不多说,我直接封装了一个类,是个layer,需要的时候直接添加layer就行  //白白原创 头文件 #pragma once #include "cocos2d.h" USING_NS_CC; const int kTagBackground=0; const int kTagClipNode=1; const int kTagTip=2; class TestLayer : public CCLayer { public: CREATE_FUNC(TestLayer); vir

c++-面向对象类的示例-求周长面积,判断体积相等-文件操作和一般操作

面向对象编程示例:求周长和面积 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; //圆的周长 double getCircleGirth(double r) { return 2 * 3.14*r; } //源的面积 double getCircleArea(double r) { return 3.14*r*r; } //用面向对象实现 //圆类 class Circle { public: v

小议头像预览裁剪上传的实现

在做头像上传的时候,浏览器默认是无法取得本地图片的,当然 HTML5 是可以的.不过IE6-8怎么破?目前比较通用的方案都是 flash 解决. 说道头像预览和裁剪,我最熟悉的就是 Discuz 的那个了,非常方便好用.不仅可以选择本地图片,还能直接调用摄像头拍摄,当然前提是你必须有个摄像头. 于是我心血来潮的想把他剥离出来给项目用,于是有就了此文..我就不说怎么提取怎么调用,就简单的谈谈他是怎么处理图片好了,反正不是我们想的那样,和我想的出入非常大. 这个插件呢,差不多分为四步处理:1. 前台

多个矩形,求覆盖面积,周长,及交点

问题:给出若干个矩形,(给的是矩形左上角和右下角坐标),求最后所得图形的面积/周长: 三个矩形如左图所示,而若要计算面积,看右图,用3个矩形各自的面积之和减去重复部分(红色和蓝色)的面积 人算很简单,但是用算法怎么实现呢? 此类问题一般都是用线段树辅助扫描法来计算: 什么是扫描法?有什么用?怎么用? 可以想象成一根假想的线,将图从左往右或从右往左或自下而上或自上而下“扫描”一遍,至于扫描的是什么则根据具体应用选择. 扫描线可以计算矩形面积.周长,可以计算线段交点,可以实现多边形扫描转换,在图的处

如?何?计?算?当?地?的?中?央?子?午?线?经?度

一. 基本概念: 1.地形图坐标系:我国的地形图采用高斯-克吕格平面直角坐标系.在该坐标系中,横轴:赤道,用Y表示:纵轴:中央 经线,用X表示:坐标原点:中央经线与赤道的交点,用O表示.赤道以南为负,以北为正:中央经线以东为正,以西为负.我国位于北半球,故纵坐标均为正值, 但为避免中央经度线以西为负值的情况,将坐标纵轴西移500公里. 2.北京54坐标系:1954年我国在北京设立了大地坐标原点,采用克拉索夫斯基椭球体,依此计算出来的各大地控制点的坐标,称为北京54坐标系. 3.GS84坐标系:即

【Cocos2dx 3.3 Lua】剪裁结点ClippingNode

参考资料: http://shahdza.blog.51cto.com/2410787/1561937 http://blog.csdn.net/jackystudio/article/details/17160973 [ClippingNode] 1.原理 ClippingNode(裁剪节点)可以用来对节点进行裁剪.ClippingNode是Node的子类,可以像普通节点一样放入Layer,Scene,Node中. 主要是根据一个模板(Stencil)切割图片的节点,生成任何形状的节点显示.