首页 > 试题广场 >

框选线段

[编程题]框选线段
  • 热度指数:249 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
在二维平面坐标系中,已知存在一条线段(图中P1->p2)和一个矩形区域,编程计算得出线段被矩形区域裁剪的新起始点。
注意以下要求:
A、线段是有方向的,裁剪得到的新线段也需要保持原线段的方向;下图中,线段的描述是P1->p2,则裁剪的结果是P3->p4,反之,如果线段描述是P2->P1,则结果是P4->P3
B、线段的起始点在矩形区域里面时,裁剪的结果则就是原始线段
C、当线段与矩形区域没有相交线段的时候,结果输出“-1”


输入描述:
依次输入矩形区域的:左下角端点坐标(x1,y1),右上角端点坐标(x2,y2),线条起点坐标(x3,y3);线条终点坐标(x4,y4)
输入格式:
第一行四个数字:x1 y1 x2 y2
第二行四个数字:x3 y3 x4 y4

数据范围:
1<=x1,x2,x3,x4,y1,y2,y3,y4<=30
x1<x2
y1<y2


输出描述:
如果能够裁剪则:
    第一行输出裁剪后的起点坐标(ansx1,ansy1)    
    第二行输出裁剪后的终点坐标(ansx2,ansy2)
    结果四舍五入保留小数点后两位
如果不能够裁剪:
    输出-1
示例1

输入

3 3 10 10
11 11
4 4

输出

(10.00,10.00)
(4.00,4.00)

说明

裁剪后起点为(10,10),终点为(4,4)
示例2

输入

3 3 10 10
11 11 14 14

输出

-1

说明

线段无被裁剪出的部分
#include <iostream>
using namespace std;
struct Point {
	float x, y;
};
struct Rect {
	Point leftBottom, rightTop;
	bool contain(const Point& pt) {
		return pt.x > leftBottom.x&& pt.x<rightTop.x && pt.y>leftBottom.y&& pt.y < rightTop.y;
	}
	void cut(Point& pt, const Point& dir) {		//根据方向向量将点裁剪到矩形上
		if (contain(pt))						//如果点在矩形内,则不需要对它裁剪
			return;
		Point offset = { 1,dir.y / dir.x };		//确定水平方向,计算垂直方向的偏移
		if (pt.x > rightTop.x)
			pt = { rightTop.x,pt.y + offset.y * (rightTop.x - pt.x) };
		else if (pt.x < leftBottom.x)
			pt = { leftBottom.x,pt.y + offset.y * (leftBottom.x - pt.x) };
		offset = { dir.x / dir.y,1 };			//确定垂直方向,计算水平方向的偏移
		if (pt.y > rightTop.y)
			pt = { pt.x + offset.x * (rightTop.y - pt.y), rightTop.y };
		else if (pt.y < leftBottom.y)
			pt = { pt.x + offset.x * (leftBottom.y - pt.y), leftBottom.y };
	}
};

istream& operator>>(istream& in, Point& pt) {
	in >> pt.x >> pt.y;
	return in;
}

int main() {
	Rect rect;
	Point p1, p2;
	Point dir;  //直线的方向向量

	cin >> rect.leftBottom >> rect.rightTop;
	cin >> p1 >> p2;
	dir = { p2.x - p1.x,p2.y - p1.y };
	rect.cut(p1, dir);
	rect.cut(p2, dir);
	if (p1.x == p2.x && p1.y == p2.y)
		printf("-1");
	else
		printf("(%0.2f,%0.2f)\n(%0.2f,%0.2f)", p1.x, p1.y, p2.x, p2.y);
	return 0;
}


编辑于 2020-06-05 13:18:08 回复(2)
#include<bits/stdc++.h>
using namespace std;
struct point{
    double x,y;
};
struct box{
    double x1,y1,x2,y2;
};
bool isInside(point x, box s){
    return s.x1<=x.x && x.x<=s.x2 && s.y1<=x.y && x.y<=s.y2;
}
bool work1(point s, point t, box a, point& ans_s, point& ans_t){
    ans_s = s;
    ans_t = t;
    int flag = 0;
    point now = s;
    int unit = 30000;
    double add_x = (t.x - s.x) / unit, add_y = (t.y - s.y) / unit;
    for(int i=0;i<unit;i++){
        now.x += add_x;
        now.y += add_y;
        if(flag ==0 && isInside(now, a)){
            ans_s = now;
            flag = 1;
        }
        if(flag == 1 && !isInside(now, a)){
            ans_t = now;
            break;
        }
    }
    if(flag == 0){
        return false;
    }
    else{
        return true;
    }
} 
int main(){
    point s,t;
    box a;
    scanf("%lf%lf%lf%lf",&a.x1, &a.y1, &a.x2, &a.y2);
    scanf("%lf%lf%lf%lf",&s.x, &s.y, &t.x, &t.y);
    point ans_s, ans_t;
    bool flag = work1(s, t, a, ans_s, ans_t);
    if(flag == true){
        printf("(%.2lf,%.2lf)\n(%.2lf,%.2lf)\n",ans_s.x,ans_s.y,ans_t.x,ans_t.y);
    }
    else{
        printf("-1\n");
    }
    return 0;
}

发表于 2020-02-20 09:36:17 回复(4)