[C++/PTA] 计算点到直线的距离一一友元函数的应用

简介: [C++/PTA] 计算点到直线的距离一一友元函数的应用

题目要求

计算点到直线的距离。首先设计一个点类Point,它有2 个私有数据成员x和y,表示点的坐标。另一个类为直线类Line,它有3 个私有数据成员a,b和c,表示直线方程ax+by+c= 0。这两个类中都说明了一个友元函数dist,用于计算一个点到直线的距离。点(x.y)到直线ax+by+c=0的距离d的计算公式如下:

语法要点: 友元函数的特点。

这是一个编程题模板。请在这里写题目描述。例如:本题目要求读入2个整数A和B,然后输出它们的和。

输入格式:

输入两行,第一行输入两个整数,表示点坐标x,y的值

在第二行中输入直线三个参数,表示直线方程的三个洗漱a,b,c.

输出格式:

计算点到直线的距离保留两位小数

输入样例:

在这里给出一组输入。例如:

5 5

2 4 3

输出样例:

在这里给出相应的输出。例如:

The distance is: 7.38

解题思路

  1. 定义 Point 和 Line 两个类,其中 Point 表示平面上的一个点,包含坐标 x 和 y;Line 表示平面上的一条直线,包含参数 a,b,c (对应直线方程 ax+by+c=0 中的系数)。
  2. 在 Point 中定义友元函数 dist(Line &, Point &) 和 Line 中定义友元函数 dist(Line &, Point &),它们分别用于计算一个点到直线的距离。

这两个友元函数其实是同一个函数,只是参数顺序不同,可以根据需要选择其中一个进行使用。

在 Point 中定义的友元函数 dist(Line &, Point &) 的作用是:

  • 将参数 Point &P 带入直线方程 ax+by+c=0,求出点 P 到直线 L 垂足的坐标 H(x0,y0):
  • 计算 PH 的长度,即为点 P 到直线 L 的距离:

在 Line 中定义的友元函数 dist(Line &, Point &) 的作用与上述类似,将参数 Line &L 带入直线方程求出直线 L 到点 P 垂足的坐标 H(x0,y0),再计算 PH 的长度。

  1. 在主函数中,首先通过输入获取参数 A,B,a1,b1,c1,分别表示点 P 的坐标、直线 L 的系数。然后创建一个 Point 对象 P 和一个 Line 对象 L。
  2. 调用 dist 函数计算 P 点到 L 直线的距离,根据测试要求使用 setprecision 控制输出精度,最后输出结果。

代码

#include<iostream>
#include<cmath>
#include<iomanip> //用于控制输出精度 
using namespace std;
class Line; //提前声明 Line 类,因为 Point 中的友元函数要用到它 
class Point {
    int x, y;
public:
    //构造函数,用于初始化 Point 对象
    Point(int X = 0, int Y = 0) {
        x = X;
        y = Y;
    }
    //公有成员函数,获取 x 坐标
    int getx() { return x; }
    //公有成员函数,获取 y 坐标
    int gety() { return y; }
    //友元函数,计算点到直线的距离
    friend double dist(Point&, Line&);
};
class Line {
    int a, b, c;
public:
    //构造函数,用于初始化 Line 对象
    Line(int A = 1, int B = 1, int C = 1) {
        a = A;
        b = B;
        c = C;
    }
    //公有成员函数,获取 a 系数
    int geta() { return a; }
    //公有成员函数,获取 b 系数
    int getb() { return b; }
    //公有成员函数,获取 c 系数
    int getc() { return c; }
    //友元函数,计算点到直线的距离
    friend double dist(Point&, Line&);
};
//友元函数,计算点到直线的距离
double dist(Point& P, Line& L) {
    double s;
    //计算直线上垂足的坐标
    double x0 = (L.b*L.b*P.x - L.a*L.b*P.y - L.a*L.c) / (L.a*L.a + L.b*L.b);
    double y0 = (-L.a*L.b*P.x + L.a*L.a*P.y - L.b*L.c) / (L.a*L.a + L.b*L.b);
    //计算距离
    s = abs((L.a*P.x + L.b*P.y + L.c) / sqrt(L.a*L.a + L.b*L.b));
    return s;
}
int main() {
    int A, B, a1, b1, c1;
    cin >> A >> B; //输入点 P 的坐标
    cin >> a1 >> b1 >> c1; //输入直线 L 的系数
    Point P(A, B); //创建 Point 对象 P
    Line L(a1, b1, c1); //创建 Line 对象 L
    //调用 dist 函数计算 P 点到 L 直线的距离,并输出结果
    if (dist(P, L) == 0) //判断距离是否为 0,下同
        cout << "The distance is: 0";
    else 
        cout << fixed << setprecision(2) << "The distance is: " << dist(P, L);
    return 0;
}

总结

该题考察C++ 类的基本定义和使用,包括类的构造函数、公有成员函数和私有成员变量等。

同时考察了友元函数的定义和使用,注意:友元函数可以访问类的私有成员变量,但并不是类的成员函数。

我是秋说,我们下次见。

目录
相关文章
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
427 15
|
9月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
339 11
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
671 12
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
542 5
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
382 4
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
647 5
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
375 2
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
254 1
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
583 12