A Circle and a Square----计算几何,判断点是否在图形内

A Circle and a Square

by _mfv_
Your submission will run against only preliminary test cases. Full test cases will run at the end of the day.

In this challenge, you must implement part of a raster graphics editor that takes the coordinates of a circle and a square as input and draws them as filled-in shapes on a rectangular canvas.


The rectangular canvas consists of uniformly sized square pixels, and is  pixels wide, and  pixels high. Each point on the canvas belongs to a pixel, the intersection of two pixels has zero area, and each pixel is completely contained within the canvas.

The Cartesian coordinate system set up in the following way:

  • Point  is the center of the top-left pixel of the canvas.
  • Point  is the center of the top-right pixel of the canvas.
  • Point  is the center of the bottom-left pixel of the canvas.
  • Point  is the center of the bottom-right pixel of the canvas.

Thus, all pixel centers have integer coordinates and if the center of a pixel has coordinates , then point belongs to the pixel if and only if  and . The two shapes should be drawn like so:

  • The circle is centered at the integer coordinates  and has non-negative integer radius . A pixel should be black as a part of the circle if and only if the Euclidean distance from the pixel's center to the center of the circle is not greater than .

image

  • The square is defined by the integer coordinates of two of its opposite corners  and . A pixel should be black as a part of the square if and only if its center falls within the square or along its border. The coordinates of different corners of the square do not coincide.

image

Given , and the definition of the circle and the square, print a raster image of the canvas where each character is either a . (denoting a white pixel outside of both shapes) or a # (denoting a black pixel that's part of a shape).

Note: The first pixel of the first line of output should correspond to the top-left corner of the canvas.

Input Format

The first line contains two space-separated integers describing the respective values of  (canvas width) and  (canvas height). 
The second line contains three space-separated integers describing the respective values of , and defining a circle with radius  centered at 
The third line contains four space-separated integers describing the respective values of  defining a square with opposite corners at  and .

Constraints

Output Format

Print  lines where each line contains  characters. Each character must be either a . (to denote a white pixel) or a #(to denote a black pixel). The first pixel of the first line of output corresponds to the top-left corner of the canvas.

Sample Input 0

20 16
9 6 5
16 14 8 14

Sample Output 0

....................
.........#..........
......#######.......
.....#########......
.....#########......
.....#########......
....###########.....
.....#########......
.....#########......
.....#########......
......#######.......
.........#.###......
..........#####.....
.........#######....
........#########...
.........#######....

Explanation 0

image

The canvas has  rows and  columns. The circle has radius  and is centered at point . The square has opposite corners located at points  and  and, as you can see, is rotated at an angle with its third corner at point  (note that its fourth corner is outside the canvas boundary). In addition, the circle and the square overlap at point .














题目链接:https://www.hackerrank.com/contests/w29/challenges/a-circle-and-a-square


好久没有这个畅快淋漓的做过计算几何了,这是Week of code 29的第三题,并不难,只是麻烦。

题意是说我给你一个圆的圆心和半径,判断哪些点在圆内,给你一个正方形的一条对角线的顶点坐标,求哪些点在正方形内。只是个单纯的判断点是否在图形内,并没有多少难度,就是要注意一点,他输入的时候坐标都是反着输入的。。。卡了我半个多小时才发现。。。。。


还有一个小知识点作为前置技能。

在正方形内,四个顶点的坐标依次为(x0,y0),(x1,y1),(x2,y2),(x3,y3),我们知道:

x1+x3=x0+x2;

x1-x3=y2-y0;

y1+y3=y0+y2;

y1-y3=x0-x2;

我们可以得出另外两个不相邻顶点的坐标:

x1=(x0+x2+y2-y0)/2

x3=(x0+x2+y0-y2)/2

y1=(y0+y2+x0-x2)/2

y3=(y0+y2-x0+x2)/2


知道这个前置技能就很好做这个题了,直接上就可以了,注意double。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#define eps 1e-7
#define _sign(x) ((x)>eps?1:((x)<-eps?2:0))
using namespace std;
bool map1[200][200];
struct Point{
    double x,y;
};
int Distance(int x1,int y1,int x2,int y2){
    return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool judge1(int x,int y,int xc,int yc,int r){
    int dis=Distance(x,y,xc,yc);
    if(r*r-dis>=0)
        return true;
    else
        return false;
}
double xmult(Point p1,Point p2,Point p){
    return (p1.x-p.x)*(p2.y-p.y)-(p2.x-p.x)*(p1.y-p.y);
}
int inside_convex(Point q,int n,Point *p){
    int s[3]={1,1,1};
    for(int i=0;i<n&&s[1]|s[2];i++){
        s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;
    }
    return s[1]|s[2];
}
int main(){
    int w,h;
    int xc,yc,x1,y1,x3,y3;
    int r;
    while(~scanf("%d%d",&h,&w)){
        scanf("%d%d%d",&yc,&xc,&r);
        scanf("%d%d%d%d",&y1,&x1,&y3,&x3);
        memset(map1,false,sizeof(map1));
        int s1,s2,s3,s4;
        s1=xc-r;s2=yc+r;
        s3=xc+r;s4=yc-r;
        for(int i=max(0,s1);i<=min(w-1,s3);i++){
            for(int j=max(0,s4);j<=min(h-1,s2);j++){
                if(judge1(i,j,xc,yc,r)){
                    map1[i][j]=true;
                }
            }
        }
        double x2=(double)(x1+x3+y3-y1)/2;
        double y2=(double)(y1+y3+x1-x3)/2;
        double x4=(double)(x1+x3+y1-y3)/2;
        double y4=(double)(y1+y3-x1+x3)/2;
        Point point[5];
        point[0].x=(double)x1;
        point[0].y=(double)y1;

        point[1].x=(double)x2;
        point[1].y=(double)y2;

        point[2].x=(double)x3;
        point[2].y=(double)y3;

        point[3].x=(double)x4;
        point[3].y=(double)y4;
        for(int i=0;i<=w-1;i++){
            for(int j=0;j<=h-1;j++){
                Point p;
                p.x=(double)i;
                p.y=(double)j;
                if(inside_convex(p,4,point)){
                    map1[i][j]=true;
                }
            }
        }
        for(int i=0;i<=w-1;i++){
            for(int j=0;j<=h-1;j++){
                if(map1[i][j])
                    printf("#");
                else
                    printf(".");
            }
            cout<<endl;
        }
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值