БлогNot. С++: ищем свойства треугольника, заданного координатами вершин на плоскости

С++: ищем свойства треугольника, заданного координатами вершин на плоскости

Эта небольшая учебная программка для треугольника, заданного координатами 3 вершин, определяет его тип - равносторонний/равнобедренный/неравносторонний и остроугольный/прямоугольный/тупоугольный. Проверена в консоли Visual Studio 2019.

Так как координаты вершин могут быть вешественными числами, сравнивать которые, в общем случае, может оказаться некорректным действием, вместо обычного == длины сторон сравниваются функцией eq, считающей 2 числа равными, если они отличаются по модулю не более, чем на значение eps (в коде 10-12).

Проверку на допустимость координат вершин делает функция correct, тем же способом проверяющая, не коллинеарны ли 3 точки на плоскости.

Использованы специфичные для Visual Studio и Windows функции русификации консоли.

#include <iostream>
#include <cmath>
#include <algorithm>
#include <windows.h>
using namespace std;

struct point {
 double x, y;
 point() : x(0), y(0) {}
 point(double x, double y) : x(x), y(y) {}
};

const double eps = 1e-12; //допустимая погрешность сравнения вещественных чисел

void order(double& a, double& b, double& c) {
 double copy[3];
 copy[0] = a; copy[1] = b; copy[2] = c;
 sort(copy, copy + 3);
 a = copy[0]; b = copy[1]; c = copy[2];
}

double eDist2(point p1, point p2) {
 return pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2);
}

bool eq(double x, double y) {
 return abs(x-y)<=eps ? true : false;
}

string getSideClassification(double a, double b, double c) {
 if (eq(a,b) && eq(b,c)) return "равносторонний";
 else if (eq(a,b) || eq(b,c)) return "равнобедренный";
 else return "неравносторонний";
}

string getAngleClassification(double a, double b, double c) {
 if (a + b > c) return "остроугольный";
 else if (eq(a + b,c)) return "прямоугольный";
 else return "тупоугольный";
}

void classifyTriangle(point p1, point p2, point p3) {
 double a = eDist2(p1, p2);
 double b = eDist2(p1, p3);
 double c = eDist2(p2, p3);
 double a0 = sqrt(a), b0 = sqrt(b), c0 = sqrt(c);
 order(a, b, c); //перед сравнением сортируем стороны!
 cout.precision(2);
 cout << "Вершины: (" << p1.x << "," << p1.y << "), (" <<
  p2.x << "," << p2.y << "), (" <<
  p3.x << "," << p3.y << "), стороны: " <<
  "(" << a0 << ", " << b0 << ", " << c0 << "), " <<
  getAngleClassification(a, b, c) << " треугольник, " << getSideClassification(a, b, c) << endl;
}

bool correct (point p1, point p2, point p3) {
 return !(fabs((p1.y - p2.y) * (p1.x - p3.x) - (p1.y - p3.y) * (p1.x - p2.x)) <= eps);
}

int main() {
 setlocale(LC_ALL, "Rus");
 SetConsoleCP(1251);
 SetConsoleOutputCP(1251);

 const int number_of_triangles = 4;
 point triangles[number_of_triangles][3] = {
  { point(3, 0), point(0, 4), point(4, 7) },
  { point(0, 0), point(1, 1), point(1, 2) },
  { point(0, 0), point(1, 1), point(2, 2) }, //не существует
  { point(0, 0), point(-3, -4), point(0, 0) }  //не существует
 };
 point p1, p2, p3;

 for (int i = 0; i < number_of_triangles; i++) {
  p1 = triangles[i][0];
  p2 = triangles[i][1];
  p3 = triangles[i][2];
  if (!correct(p1, p2, p3)) {
   cout.precision(2);
   cout << "Вершины: (" << p1.x << "," << p1.y << "), (" <<
    p2.x << "," << p2.y << "), (" <<
    p3.x << "," << p3.y << "), треугольника не существует" << endl;
  }
  else classifyTriangle(p1, p2, p3);
 }
 
 cin.get(); return 0;
}

теги: учебное алгоритм c++

10.05.2020, 16:22; рейтинг: 159