1038 - Eyeball Benders

``Eyeball benders" are a popular kind of puzzle in which the reader must identify a common object based on a close- up view of a part of that object. For instance, an image that looks like a regular array of colored cones might be a view of an open box of new crayons. Figure 1 shows an example where the puzzle is on the left and the solution is on the right.

\epsfbox{p3269a.eps}

Figure 1. A sample eyeball-bender puzzle and solution image (a floppy disk)

You must verify solutions to a simplified version of the ``eyeball bender" puzzle. You will be given a number of pairs of images, each one a collection of line segments. All line segments will be either horizontal or vertical, and they include their endpoints. Figure 2 shows an example.


You must determine whether the images form a valid pair in which the first image is a magnified view of some portion of the second image. Lines are assumed to have zero thickness in both images. At least one endpoint in the puzzle image of a valid pair must be an endpoint of a line segment in the solution image.

\epsfbox{p3269b.eps}

Figure 2. The left image is the portion of the right image inside the dotted rectangle, magnified 3 times.

Coordinates describe relative positions and scale within a single image. The coordinates in one image do not necessarily use the same origin or scale as those in the other image. The magnification of the puzzle image relative to the solution image is required to be greater than or equal to 1. For Figure 2, your program should determine that this is a valid puzzle/solution image pair.

Input 

The input consists of multiple cases. The input for each case begins with two positive integers M and N(1$ \le$MN$ \le$50)M is the number of line segments in the puzzle image. N is the number of line segments in the proposed solution image. The following lines contain M + N pairs of points. The first M pairs of points are the endpoints of the line segments in the puzzle image; the remaining N pairs are the endpoints of the line segments in the proposed solution image. The x and y coordinates for each pair satisfy -100$ \le$xy$ \le$100 and are given to at most three decimal places of precision. All input values are separated by white space (blanks or new line characters).


No pair of distinct points in a given image will be closer than .005 to another (relative to the scale of the image) and all segments will have length at least .005. No two horizontal segments overlap and no two vertical segments overlap. However, horizontal segments may intersect vertical segments either internally or at segment endpoints.


The input data for the last case is followed by a line consisting of the integers `0 0'.

Output 

For each input case, display the case number (1, 2, ...) followed by the words `valid puzzle' if the proposed solution image matches a closed rectangular sub-region of the puzzle image (including at least one endpoint), magnified by a factor of one or greater, and possibly translated by some amount. Line segments that are not included in the puzzle image will be at least 0.005 distant from the rectangle.


If the match condition fails to hold, print `impossible'. Follow the format of the sample output.

Sample Input 

3 12                                                                        
9 8 7.5 8 1.5 8 1.5 3.5                                                     
0 5 9 5                                                                     
4 2 8 2 5 7 2 7 10 6 8 6 8 7 8 4                                               
1 9 8 9 
9 3 7 3 4 10 4 5 
4 2 4 4 5 8 5 7 3 6 6 6 0 3 3 3 5 1 5 3 
4 12 
-50 -5 50 -5 0 10 0 -10 50 5 -50 5 -50 0 50 0 
4 2 8 2 5 7 2 7 10 6 8 6 8 7 8 4 
1 9 8 9 
9 3 7 3 4 10 4 5 
4 2 4 4 5 8 5 7 3 6 6 6 0 3 3 3 5 1 5 3 
0 0

Sample Output 

Case 1: valid puzzle
   
Case 2: impossible



#include<stdio.h>
#include<math.h>
struct line
{
	double x1,y1,x2,y2;
};
struct point
{
	double x,y;
};
const double delta=1e-6;
bool ok;
int T,n,m,i,j,k;
double scale;
point pL,pS;
line tL;
line L[60],S[60],SN[60];
line in()
{
	double tmp;
	line t;
	scanf("%lf %lf %lf %lf",&t.x1,&t.y1,&t.x2,&t.y2);
	if(t.x1>t.x2+delta)
	{
		tmp=t.x1;
		t.x1=t.x2;
		t.x2=tmp;
	}
	if(t.y1>t.y2+delta)
	{
		tmp=t.y1;
		t.y1=t.y2;
		t.y2=tmp;
	}
	return t;
}

bool same(double x,double y)
{
	return (y-delta<x && x<y+delta);
}

bool findS(line p)
{
	int i;
	for(i=0;i<n;i++)
	{
		if(same(p.x1,p.x2)&&same(L[i].x1,L[i].x2)&&same(p.x1,L[i].x1))
			if(L[i].y1<=p.y1&&p.y2<=L[i].y2)
				return true;
		if(same(p.y1,p.y2)&&same(L[i].y1,L[i].y2)&&same(p.y1,L[i].y1))
			if(L[i].x1<=p.x1&&p.x2<=L[i].x2)
				return true;
	}
	return false;
}

bool findL(line p)
{
	int i;
	for(i=0;i<m;i++)
	{
		if(same(p.x1,p.x2)&&same(SN[i].x1,SN[i].x2)&&same(p.x1,SN[i].x1))
			if(SN[i].y1<=p.y1 && p.y2<=SN[i].y2)
				return true;
		if(same(p.y1,p.y2)&&same(SN[i].y1,SN[i].y2)&&same(p.y1,SN[i].y1))
			if(SN[i].x1<=p.x1&&p.x2<=SN[i].x2)
				return true;
	}
	return false;
}

double dis(double x,double y)
{
	return sqrt(x*x+y*y);
}

bool check()
{
	double MaxX,MaxY,MinX,MinY;
	int i,j,k;
	MaxX=MinX=pL.x;
	MaxY=MinY=pL.y;
	for(i=0;i<m;i++)
	{
		SN[i].x1=(S[i].x1-pS.x)*scale + pL.x;
		SN[i].y1=(S[i].y1-pS.y)*scale + pL.y;
		SN[i].x2=(S[i].x2-pS.x)*scale + pL.x;
		SN[i].y2=(S[i].y2-pS.y)*scale + pL.y;
		if(!findS(SN[i]))
			return false;
		if(SN[i].x1<MinX)
			MinX=SN[i].x1;
		if(SN[i].x2>MaxX)
			MaxX=SN[i].x2;
		if(SN[i].y1<MinY)
			MinY=SN[i].y1;
		if(SN[i].y2>MaxY)
			MaxY=SN[i].y2;
	}
	for(i=0;i<n;i++)
	{
		if(same(L[i].x1,L[i].x2))
		{
			if(L[i].x1>MaxX)
			{
				if(L[i].y1>MaxY)
				{
					if(dis(L[i].x1-MaxX,L[i].y1-MaxY)<0.005)
						return false;
				}
				else if( L[i].y2<MinY)
				{
					if(dis(L[i].x1-MaxX,L[i].y2-MinY)<0.005)
						return false;
				}
				else if(L[i].x1-MaxX<0.005)
					return false;
			}
			else if(L[i].x2<MinX)
			{
				if(L[i].y1>MaxY)
				{
					if(dis(L[i].x2-MinX,L[i].y1-MaxY)<0.005)
						return false;
				}
				else if(L[i].y2<MinY)
				{
					if(dis(L[i].x2-MinX,L[i].y2-MinY)<0.005)
						return false;
				}
				else if(MinX-L[i].x2<0.005)
					return false;
			}
			else
			{
				if(L[i].y2<MinY-0.005 || L[i].y1>MaxY + 0.005)
					continue;
				if(L[i].y2<MinY || L[i].y1>MaxY)
					return false;
				tL=L[i];
				if(tL.y1<MinY)
					tL.y1=MinY;
				if(tL.y2>MaxY)
					tL.y2=MaxY;
				if(!findL(tL))
					return false;
			}
		}
		else
		{
			if(L[i].y1>MaxY)
			{
				if(L[i].x1>MaxX)
				{
					if(dis(L[i].x1-MaxX,L[i].y1-MaxY)<0.005)
						return false;
				}
				else if(L[i].x2<MinX)
				{
					if(dis(L[i].x2-MinX,L[i].y1-MaxY)<0.005)
						return false;
				}
				else if(L[i].y1-MaxY<0.005)
					return false;
			}
			else if(L[i].y2<MinY)
			{
				if(L[i].x1>MaxX)
				{
					if(dis(L[i].x1-MaxX,L[i].y2-MinY)<0.005)
						return false;
				}
				else if(L[i].x2<MinX)
				{
					if(dis(L[i].x2-MinX,L[i].y2-MinY)<0.005)
						return false;
				}
				else if(MinY-L[i].y2<0.005)
					return false;
			}
			else
			{
				if(L[i].x2<MinX-0.005||L[i].x1>MaxX+0.005)
					continue;
				if(L[i].x2<MinX || L[i].x1>MaxX)
					return false;
				tL=L[i];
				if(tL.x1<MinX)
					tL.x1=MinX;
				if(tL.x2<MaxX)
					tL.x2=MaxX;
				if(!findL(tL))
					return false;
			}
		}
	}
	return true;
}

void work()
{
	int k;
	if(m==1)
	{
		scale=0.005/(S[0].x2-S[0].x1+S[0].y2-S[0].y1);
		ok=scale<=1 && check();
	}
	else for(k=0;k<n;k++)
		if((L[k].x1-L[k].x2)*(S[1].x1-S[1].x2) || (L[k].y1-L[k].y2)*(S[1].y1-S[1].y2))
		{
			if(S[1].x1!=S[1].x2)
			{
				if(same(S[1].y1,pS.y))
				{
					if(!same(S[1].x1,pS.x))
						scale=(L[k].x1-pL.x)/(S[1].x1-pS.x);
					else
						scale=(pL.x-L[k].x2)/(pS.x-S[1].x2);
				}
				else 
					scale=(L[k].y1-pL.y)/(S[1].y1-pS.y);
			}
			else
			{
				if(same(S[1].x1,pS.x))
				{
					if(!same(S[1].y1,pS.y))
						scale=(L[k].y1-pL.y)/(S[1].y1-pS.y);
					else
						scale=(pL.y-L[k].y2)/(pS.y-S[1].y2);
				}
				else
					scale=(L[k].x1-pL.x)/(S[1].x1-pS.x);
			}
			ok=scale<=1&&scale>delta&&check();
			if(ok)
				return ;
			
	}
}

int main()
{
	T=0;
	while(scanf("%d %d",&m,&n) && (m||n))
	{
		for(i=0;i<m;i++)
			S[i]=in();
		for(i=0;i<n;i++)
			L[i]=in();
		ok=false;
		for(i=0;i<n;i++)
			for(j=0;j<m;j++) if(!ok)
			{
				tL=S[0];
				S[0]=S[j];
				S[j]=tL;
				pL.x=L[i].x1;
				pL.y=L[i].y1;
				pS.x=S[0].x1;
				pS.y=S[0].y1;
				work();
				if(ok)
					break;
				pL.x=L[i].x2;
				pL.y=L[i].y2;
				pS.x=S[0].x2;
				pS.y=S[0].y2;
				work();
				if(ok)
					break;
			}
			if(ok)
				printf("Case %d: valid puzzle\n\n",++T);
			else
				printf("Case %d: impossible\n\n",++T);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来教你如何用Processing实现眼珠转动和眨眼的旺仔吧! 首先,我们需要导入Processing的库,并定义一些全局变量: ```python import processing.core.PApplet as PApplet class Sketch(PApplet): def setup(self): self.size(400, 400) self.background(255) self.angle = 0 self.eyeball_x = 150 self.eyeball_y = 150 self.eye_width = 100 self.eye_height = 80 self.eyelid_height = 20 self.eyelid_speed = 10 self.eyelid_pos = 0 ``` 接下来,我们可以定义一个函数来绘制旺仔的眼睛: ```python def draw_eyes(self): self.fill(255) self.stroke(0) self.strokeWeight(2) # 绘制眼球 self.ellipse(self.eyeball_x, self.eyeball_y, self.eye_width, self.eye_height) # 绘制瞳孔 self.fill(0) self.ellipse(self.eyeball_x + self.eye_width / 4 * self.cos(self.angle), self.eyeball_y - self.eye_height / 4 * self.sin(self.angle), self.eye_width / 2, self.eye_height / 2) # 绘制眼睑 self.fill(255) self.noStroke() self.rect(0, 0, self.width, self.eyelid_pos) self.rect(0, self.height - self.eyelid_pos, self.width, self.eyelid_pos) ``` 其中,眼球和瞳孔的位置可以通过改变全局变量 `eyeball_x` 和 `eyeball_y` 的值来实现,眼睑的高度可以通过改变全局变量 `eyelid_pos` 的值来实现。 然后,我们可以在 `draw` 函数中调用 `draw_eyes` 函数来绘制旺仔的眼睛,并通过 `frameCount` 计算眼睛的转动角度: ```python def draw(self): self.background(255) # 计算眼睛转动的角度 self.angle = self.radians(self.frameCount) # 计算眼睑的位置 if self.frameCount % self.eyelid_speed == 0: self.eyelid_pos = self.constrain(self.eyelid_pos + 1, 0, self.eyelid_height) # 绘制眼睛 self.pushMatrix() self.translate(self.width / 2, self.height / 2) self.draw_eyes() self.popMatrix() ``` 完整的代码如下: ```python import processing.core.PApplet as PApplet class Sketch(PApplet): def setup(self): self.size(400, 400) self.background(255) self.angle = 0 self.eyeball_x = 150 self.eyeball_y = 150 self.eye_width = 100 self.eye_height = 80 self.eyelid_height = 20 self.eyelid_speed = 10 self.eyelid_pos = 0 def draw_eyes(self): self.fill(255) self.stroke(0) self.strokeWeight(2) # 绘制眼球 self.ellipse(self.eyeball_x, self.eyeball_y, self.eye_width, self.eye_height) # 绘制瞳孔 self.fill(0) self.ellipse(self.eyeball_x + self.eye_width / 4 * self.cos(self.angle), self.eyeball_y - self.eye_height / 4 * self.sin(self.angle), self.eye_width / 2, self.eye_height / 2) # 绘制眼睑 self.fill(255) self.noStroke() self.rect(0, 0, self.width, self.eyelid_pos) self.rect(0, self.height - self.eyelid_pos, self.width, self.eyelid_pos) def draw(self): self.background(255) # 计算眼睛转动的角度 self.angle = self.radians(self.frameCount) # 计算眼睑的位置 if self.frameCount % self.eyelid_speed == 0: self.eyelid_pos = self.constrain(self.eyelid_pos + 1, 0, self.eyelid_height) # 绘制眼睛 self.pushMatrix() self.translate(self.width / 2, self.height / 2) self.draw_eyes() self.popMatrix() if __name__ == '__main__': sketch = Sketch() sketch.runSketch() ``` 运行程序后,你就可以看到一个眼珠转动和眨眼的旺仔了!你可以根据自己的需求,修改代码来实现更多的动画效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值