Предизвикателство · C# · .NET

Стереометрично ядро

Собствена геометрична библиотека на C#, която от описание на тяло пресмята разстояния, ъгли и сечения. Покрита е с тестове и има конзолен интерфейс. Без готови геометрични библиотеки: всяка формула е твоя.

ЗащоThree.js рисува фигурите. Това ядро ги разбира: знае колко е ъгълът и може да го докаже.
За проектаКогато AI предложи отговор на задача, ядрото може да го провери. Това е независима проверка, която никой езиков модел не дава сам.
За журитоИзцяло авторски код, покрит с тестове. Точно това се оценява в критерия „Реализация“.

Правила на играта

Етапи

0

Структура на решението

Три проекта в едно решение: библиотека, конзола и тестове.

dotnet new sln -n Stereo
dotnet new classlib -n Stereo.Core
dotnet new console  -n Stereo.Repl
dotnet new xunit    -n Stereo.Tests
dotnet sln add Stereo.Core Stereo.Repl Stereo.Tests
dotnet add Stereo.Repl  reference Stereo.Core
dotnet add Stereo.Tests reference Stereo.Core

Готово, когато: dotnet build и dotnet test минават, а в git има първи commit.

1

Вектор

Основата на всичко. Започни оттук:

public readonly record struct Vec3(double X, double Y, double Z)
{
    public static Vec3 operator +(Vec3 a, Vec3 b) => new(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
    public static Vec3 operator -(Vec3 a, Vec3 b) => new(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
    public static Vec3 operator *(double k, Vec3 v) => new(k * v.X, k * v.Y, k * v.Z);

    // твоят ред:
    public double Dot(Vec3 o)   => throw new NotImplementedException();
    public Vec3   Cross(Vec3 o) => throw new NotImplementedException();
    public double Length       => throw new NotImplementedException();
    public Vec3   Normalized() => throw new NotImplementedException();
}

Готово, когато: има тестове за скаларно и векторно произведение, включително че a × b е перпендикулярно на a и на b.

2

Права, равнина и измервания

Изродените случаи са част от задачата. Три точки на една права не определят равнина. Права, успоредна на равнина, няма пресечна точка. Избери подход (изключение, TryXxx или null), приложи го последователно и защити избора си.

Готово, когато: всяка функция има поне един тест с ръчно пресметнат отговор и поне един тест за изроден случай.

3

Тела

Строители, които връщат именувани върхове, например Dictionary<string, Vec3> или собствен клас:

Координатната система е твое решение. Добре избраната прави всички сметки по-прости.

Готово, когато: строителите минават тестовете от таблицата по-долу.

4

Тестове с отговори от учебника

Първи комплект. Добави поне още 10 задачи от учебника, с отговорите от края му.

ТялоКаквоОчаквано
Куб, a = 4|AC1|6.9282 (4√3)
Куб, a = 4∠(AC1, ABC)35.26°
Куб, a = 4d(A, BDA1)2.3094 (4/√3)
Куб, a = 4d(AA1, BD), кръстосани прави2.8284 (2√2)
Пирамида, n = 4, a = 6, h = 4|MA|5.8310 (√34)
Пирамида, n = 4, a = 6, h = 4∠(MBC, ABC)53.13°
Пирамида, n = 4, a = 6, h = 4∠(MA, ABC)43.31°
Пирамида, n = 4, a = 6, h = 4d(O, MBC)2.4
Правилен тетраедър, a = 6височина4.8990 (a√(2/3))
Правилен тетраедър, a = 6∠(ръб, основа)54.74°
Правилен тетраедър, a = 6∠(две стени)70.53°
[Fact]
public void Cube_SpaceDiagonal()
{
    var p = Solids.Cube(4);
    Assert.Equal(4 * Math.Sqrt(3), Geo.Distance(p["A"], p["C1"]), 1e-9);
}

Готово, когато: всички тестове са зелени. Ако тест не минава, първо провери отговора: и учебниците грешат понякога.

5

Конзолен интерфейс

Малък език за команди на български. Сесията изглежда така:

> куб 4
Точки: A B C D A1 B1 C1 D1
> разстояние A C1
6.9282
> ъгъл права A C1 равнина A B C
35.26°
> пирамида 4 6 4
Точки: A B C D M O
> ъгъл равнина M B C равнина A B C
53.13°
> разстояние A Q
Грешка: няма точка Q. Налични: A B C D M O

Готово, когато: 20 грешни команди подред не срива програмата. Тествай с приятел, който не знае синтаксиса.

★ 6

Проверител

Командата провери приема твърдение и казва дали е вярно:

> провери ъгъл права A C1 равнина A B C = 45
✗ Грешно. Изчислено: 35.26°, твърдяно: 45°
> провери разстояние A C1 = 6.93
✓ Вярно (в рамките на 0.01)

Това е мостът към твоя проект. Същото ядро, извикано от backend-а, проверява отговора на Qwen, преди потребителят да го види.

★ 7

Сечение

Най-трудното. Команда сечение K L N намира сечението на тялото с равнината през три точки и връща върховете на многоъгълника по реда на обхождане, заедно с неговото лице.

Подсказка за подреждането

Намери пресечните точки на равнината с всеки ръб. После ги сортирай по ъгъл около техния център, измерен в самата равнина. За целта построй два перпендикулярни вектора в нея с Cross.

Въпроси за размисъл