C++第13周(春)项目3 - 与圆心相连的直线

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接

【项目3 - 与圆心相连的直线】
  在项目1中定义的Point(点)类和Circle(圆)类基础上,设计一种方案,输出给定一点p与圆心相连成的直线与圆的两个交点。
  提示:

  

参考解答:

方案1:用引用类型参数获得结果

#include <iostream>
#include<Cmath>
using namespace std;
class Circle;  //由于在Point中声明友元函数crossover_point中参数中用了Circle,需要提前声明
class Point
{
public:
    Point(double a=0,double b=0):x(a),y(b) {}		//构造函数
    friend ostream & operator<<(ostream &,const Point &);//重载运算符“<<”
    friend void crossover_point(Point &p,Circle &c, Point &p1,Point &p2 ) ;  //求交点的友元函数
protected:										 //受保护成员
    double x,y;
};
ostream & operator<<(ostream &output,const Point &p)
{
    output<<"["<<p.x<<","<<p.y<<"]";
    return output;
}

class Circle:public Point //circle是Point类的公用派生类
{
public:
    Circle(double a=0,double b=0,double r=0):Point(a,b),radius(r) { } //构造函数
    friend ostream &operator<<(ostream &,const Circle &);//重载运算符“<<”
    friend void crossover_point(Point &p,Circle &c, Point &p1,Point &p2 ) ;  //求交点的友元函数
protected:
    double radius;
};

//重载运算符“<<”,使之按规定的形式输出圆的信息
ostream &operator<<(ostream &output,const Circle &c)
{
    output<<"Center=["<<c.x<<", "<<c.y<<"], r="<<c.radius;
    return output;
}

//给定一点p,求出该点与圆c的圆心相连成的直线与圆的两个交点p1和p2
//关键问题是求得的交点如何返回
//方案1:利用引用类型的形式参数,注意,下面的p1和p2将“带回”求得的结果
//crossover_point函数已经声明为Point和Circle类的友元函数,类中私有成员可以直接访问
void crossover_point(Point &p, Circle &c, Point &p1,Point &p2 )
{
    p1.x = (c.x + sqrt(c.radius*c.radius/(1+((c.y-p.y)/(c.x-p.x))*((c.y-p.y)/(c.x-p.x)))));
    p2.x = (c.x - sqrt(c.radius*c.radius/(1+((c.y-p.y)/(c.x-p.x))*((c.y-p.y)/(c.x-p.x)))));
    p1.y = (p.y + (p1.x -p.x)*(c.y-p.y)/(c.x-p.x));
    p2.y = (p.y + (p2.x -p.x)*(c.y-p.y)/(c.x-p.x));
}

int main( )
{
    Circle c1(3,2,4);
    Point p1(1,1),p2,p3;

    crossover_point(p1,c1, p2, p3);

    cout<<"点p1: "<<p1<<endl;
    cout<<"与圆c1: "<<c1<<endl;
    cout<<"的圆心相连,与圆交于两点,分别是:"<<endl;
    cout<<"交点1: "<<p2<<endl;
    cout<<"交点2: "<<p3<<endl;
    return 0;
}

方案2:定义一个包含两个点的结构体,专门用于返回值(定义成类进行封装可能更好)

#include <iostream>
#include<Cmath>
using namespace std;
class Circle;  //由于在Point中声明友元函数crossover_point中参数中用了Circle,需要提前声明
struct DoublePoint;  //也先声明,Point中声明友元函数crossover_point中要用到
class Point
{
public:
    Point(double a=0,double b=0):x(a),y(b) {}		//构造函数
    friend ostream & operator<<(ostream &,const Point &);//重载运算符“<<”
    friend DoublePoint crossover_point(Point &p,Circle &c) ;  //求交点的友元函数
protected:										 //受保护成员
    double x,y;
};
ostream & operator<<(ostream &output,const Point &p)
{
    output<<"["<<p.x<<","<<p.y<<"]";
    return output;
}

class Circle:public Point //circle是Point类的公用派生类
{
public:
    Circle(double a=0,double b=0,double r=0):Point(a,b),radius(r) { } //构造函数
    friend ostream &operator<<(ostream &,const Circle &);//重载运算符“<<”
    friend DoublePoint crossover_point(Point &p,Circle &c) ;  //求交点的友元函数
protected:
    double radius;
};

//重载运算符“<<”,使之按规定的形式输出圆的信息
ostream &operator<<(ostream &output,const Circle &c)
{
    output<<"Center=["<<c.x<<", "<<c.y<<"], r="<<c.radius;
    return output;
}

struct DoublePoint   //专门用于返回值的结构体类型
{
    Point p1;
    Point p2;
};

//给定一点p,求出该点与圆c的圆心相连成的直线与圆的两个交点
//方案2:结果返回到DoublePoint类型的结构体中
//crossover_point函数已经声明为Point和Circle类的友元函数,类中私有成员可以直接访问
DoublePoint crossover_point(Point &p, Circle &c)
{
    DoublePoint pp;
    pp.p1.x = (c.x + sqrt(c.radius*c.radius/(1+((c.y-p.y)/(c.x-p.x))*((c.y-p.y)/(c.x-p.x)))));
    pp.p2.x = (c.x - sqrt(c.radius*c.radius/(1+((c.y-p.y)/(c.x-p.x))*((c.y-p.y)/(c.x-p.x)))));
    pp.p1.y = (p.y + (pp.p1.x -p.x)*(c.y-p.y)/(c.x-p.x));
    pp.p2.y = (p.y + (pp.p2.x -p.x)*(c.y-p.y)/(c.x-p.x));
    return pp;
}

int main( )
{
    Circle c1(3,2,4);
    Point p1(1,1);
    DoublePoint pp;

    pp = crossover_point(p1,c1);

    cout<<"点p1: "<<p1<<endl;
    cout<<"与圆c1: "<<c1<<endl;
    cout<<"的圆心相连,与圆交于两点,分别是:"<<endl;
    cout<<"交点1: "<<pp.p1<<endl;
    cout<<"交点2: "<<pp.p2<<endl;
    return 0;
}
=================== 迂者 贺利坚 CSDN博客专栏=================
|== IT学子成长指导专栏 专栏文章的分类目录(不定期更新) ==|
|== C++ 课堂在线专栏  贺利坚课程教学链接(分课程年级) ==|
|== 我写的书——《逆袭大学——传给IT学子的正能量》    ==|
===== 为IT菜鸟起飞铺跑道,和学生一起享受快乐和激情的大学 =====
时间: 2025-01-21 02:02:59

C++第13周(春)项目3 - 与圆心相连的直线的相关文章

2013级C++第13周(春)项目——继承的进一步话题与GUI应用开发

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 第一部分 程序阅读:阅读下面类的定义,请说出在测试函数中不同情况的调用产生的结果 #include <iostream> using namespace std; class A { protected: int a,b; public: A(int aa, int bb):a(aa), b(bb) {} void printA() { co

C++第13周(春)项目1 - 点、圆的关系

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [项目1 - 点.圆的关系](1)先建立一个Point(点)类,包含数据成员x,y(坐标点):(2)以Point为基类,派生出一个Circle(圆)类,增加数据成员(半径),基类的成员表示圆心:(3)编写上述两类中的构造.析构函数及必要运算符重载函数(本项目主要是输入输出):(4)定义友元函数int locate,判断点p与圆的位置关系(返回值

C++第13周(春)项目2 - 圆的比较

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [项目2 - 圆的比较] 在项目1的基础上,在圆类上重载关系运算符(6种),使之能够按圆的面积比较两个圆的大小.自编main函数完成测试. 参考解答: #include <iostream> #include<Cmath> using namespace std; class Point { public: Point(doubl

2013级C++第2周(春)项目——结构体应用大体验

课程主页在:http://blog.csdn.net/sxhelijian/article/details/11890759,由课程主页,可以看到完整教学方案,所有参考解答 第一部分 结构体应用 [项目1-学生成绩统计]   每位同学的信息学号.姓名.C++.高数.英语成绩,定义一个学生成绩的结构体数组,其中的数据成员包括学号(char num[12]).姓名(name).三门课的成绩(grade).总分(score).均分(average)). (1)从键盘上输入N名学生的信息(N定义为常变量

2013级C++第11周(春)项目——通过继承拥有基类的资源

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 (注:本课资料由第9周直接到第11周,因为第10周是我校春假期,全校休课.春假,实际是五一.清明.端午打包一起休息,这亲戚的做法对按周安排活动的学校更好一些.) 第一部分 程序阅读 程序阅读1:  #include<iostream> using namespace std; class A { private: int x; protect

C++第2周(春)项目3 文件+结构体实现实用系统

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [项目3-文件+结构体实现实用系统]score.txt(本文后提供了一部分数据,自行copy建文本文件)中是一些同学的学号.姓名.C++.高数.英语成绩,利用前两个项目中定义的结构体数组,读取文件中的数据,完成下面的应用: (1)从文件中读出数据,存放到结构体数组中: 博文"C++文件操作初体验"http://blog.csdn.ne

2013级C++第9周(春)项目——运算符重载(二)

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [程序阅读]阅读程序"简单C++学生信息管理系统",找出其中出现构造函数.友元函数.运算符重载.静态数成员语法现象出现的位置,仔细体会其用法,在以后的设计中能够灵活应用有关方法和技巧 项目1-3直接复制第8周的代码,加入要求的运算符重载定义后,作为第9周的任务另外发博文.[项目1]在第8周项目1基础上(1)再定义一目运算符 -,-c相

2013级C++第15周(春)项目——输入输出流及文件文件操作

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 本周程序阅读及程序调试中需要的文件,请到http://pan.baidu.com/s/1qW59HTi下载. 第一部分 阅读程序(运行程序时,由上面的链接下载源代码)1.阅读教材例13.1到例13.7的程序,根据所用到的函数在功能上的限制,自己设计输入的测试数据,运行程序.(1)与自己的期望结果相对照,理解各个函数的用法:(2)深入理解数据流类

C++第7周(春)项目3 成员函数、友元函数和一般函数有区别

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [项目3-成员函数.友元函数和一般函数有区别] 阅读下面的程序,仔细阅读注释.然后模仿完成求点类中距离的任务. //例:使用成员函数.友元函数和一般函数的区别 #include <iostream> using namespace std; class Time { public: Time(int h,int m,int s):hour(h