DEV Community

Nomon
Nomon

Posted on

Пересечение траекторий через области (C#)

Задача:
Представьте, что у нас есть две точки на плоскости — принц и принцесса. Между ними находятся несколько планет, каждая из которых представлена окружностью с определённым радиусом. Наша цель — посчитать, сколько раз траектория, соединяющая принца и принцессу, пересекает границы этих планет.

Как мы решаем эту задачу:
Для этого я написал программу на C#, которая помогает вычислить количество таких пересечений. Давайте разберём её шаг за шагом.

Основной цикл программы

using CAMP.hw3;

int.TryParse(Console.ReadLine(), out var testCases);

while (testCases-- > 0)
{
    var addressParts = Console.ReadLine()?.Split(" ", StringSplitOptions.RemoveEmptyEntries)
        .Select(int.Parse)
        .ToArray() ?? [];

    var prince = new Pointt(addressParts[0], addressParts[1]);
    var princess = new Pointt(addressParts[2], addressParts[3]);

    int.TryParse(Console.ReadLine(), out var planetsCount);

    var crossing = 0;
    while(planetsCount-- > 0)
    {
        var Planet = new Planet(Console.ReadLine());

        var princeInside = Planet.Contains(prince);
        var princessInside = Planet.Contains(princess);
        var crosses = princeInside ^ princessInside;
        crossing += crosses ? 1 : 0; 
    }
    Console.WriteLine(crossing);
}

Enter fullscreen mode Exit fullscreen mode

Что здесь происходит:

  1. Программа начинает с того, что считывает количество тестов, которые нужно выполнить.
  2. Для каждого теста она считывает координаты принца и принцессы — это будут две точки на плоскости.
  3. Далее, программа узнаёт, сколько планет нужно учесть. Каждая планета описана своими координатами (центр окружности) и радиусом.
  4. Для каждой планеты проверяется: находится ли принц внутри планеты? А принцесса? Если один из них внутри планеты, а другой снаружи, это значит, что линия между ними пересекает границу планеты. Каждый такой пересечение добавляется в итоговый счётчик.
  5. В конце программы выводится количество пересечений для каждой пары принц-принцесса.

Описание структуры планеты

namespace CAMP.hw3;

public struct Planet (Pointt center, int radious)
{
    public Pointt Center {get; init;} = center;
    public int Radious {get; init;} = radious;

    public Planet (string? parts) : this(new(), 0)
    {
        var parsedParts = parts?.Split(" ", StringSplitOptions.RemoveEmptyEntries)
            .Select(int.Parse)
            .ToArray() ?? [];

        Center = new Pointt(parsedParts[0], parsedParts[1]);
        Radious = parsedParts[3];
    }

    public bool Contains(Pointt point)
    {
        var a = Center.X - point.X;
        var b = Center.Y - point.Y;
        var cSquared = a * a + b * b;
        var c = Math.Sqrt(cSquared);

        return c <= Radious;
    }
}

Enter fullscreen mode Exit fullscreen mode

Объяснение:

  • Структура Planet описывает каждую планету как окружность на плоскости. У окружности есть центр и радиус.
  • Когда мы создаём объект планеты, программа принимает строку с координатами и радиусом, разбирает её, инициализируя соответствующие параметры.
  • Важная часть здесь — это метод Contains, который проверяет, находится ли точка (например, принц или принцесса) внутри планеты. Для этого вычисляется расстояние от центра планеты до точки, и если это расстояние меньше или равно радиусу планеты, значит точка находится внутри.

Описание структуры точки

namespace CAMP.hw3;

public readonly struct Pointt (int x, int y)
{
    public int X {get; init;} = x;
    public int Y {get; init;} = y;
}

Enter fullscreen mode Exit fullscreen mode

Что делает эта часть кода:

  • Структура Pointt описывает точку на плоскости с координатами X и Y.
  • Эти значения инициализируются при создании объекта, и они доступны только для чтения (read-only), что делает точки неизменяемыми после их создания.

Итог:
В итоге программа эффективно решает задачу пересечения траекторий, проверяя для каждой планеты, пересекается ли она с отрезком между двумя точками. Структуры Planet и Pointt помогают описать ключевые объекты, а метод Contains использует простую геометрию для определения, попадает ли точка внутрь окружности.

Top comments (0)