review(drawing): правки по ревью реализации Codex (угловой размер)

- описание (x3,y3) и сообщение об ошибке: угол выбирает angleType, не точка дуги
- тест angleType=Max (лучи 0°/45° → 135° тупой супплемент): min=45/max=135/more=315
- спек дополнен находкой о трёх типах угла

241 тест зелёный, сборка Release чистая.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 19:58:15 +03:00
parent 246233727c
commit 86a5a52347
4 changed files with 42 additions and 9 deletions
@@ -6,10 +6,27 @@
## Уточнение по реализации (важно)
Спайк изначально решил, что измеряемый сектор выбирает положение дуги `(x3,y3)`. **При реализации
выяснилось иначе:** сектор (90° vs 270°) выбирает **`angleType`** (`ksADMinAngle`/`MaxAngle`/`MoreAngle`),
выяснилось иначе:** какой угол измерять, выбирает **`angleType`** (`ksADMinAngle`/`MaxAngle`/`MoreAngle`),
а `(x3,y3)` лишь позиционирует размерную дугу и задаёт её радиус. (270° в спайке возникал потому, что
`X3/Y3` не были заданы = совпадали с вершиной → вырождение.) Проверено: `angleType=Min`→90°,
`angleType=More`→270° на одной геометрии. Тест #8 и описания инструмента/сервиса исправлены под это.
`X3/Y3` не были заданы = совпадали с вершиной → вырождение.)
Три типа дают **три разных угла** (проверено на лучах 0° и 45°):
- `Min` (`ksADMinAngle`) → **45°** (острый);
- `Max` (`ksADMaxAngle`) → **135°** (тупой супплемент, 180−45);
- `More` (`ksADMoreAngle`) → **315°** (рефлексный, 360−45).
Тесты (#8 More→270 на 90°, Max→135 на 45°) и описания инструмента/сервиса исправлены под это.
## Правки по ревью Codex (реализация)
- **#1** описание параметра `x3,y3` в инструменте переформулировано (точка позиционирует дугу; угол
выбирает `angleType`, не она).
- **#2** сообщение пост-проверки углового больше не винит `(x3,y3)` — указывает на коллинеарность сторон.
- **#3** добавлен интеграционный тест `angleType=Max` (лучи 0°/45° → 135°) — покрыл маппинг `ksADMaxAngle`,
отличный от `Min`/`More`.
- **#4** (откат радиального не тестируется) — **отклонено с обоснованием:** как у диаметрального
(`radius>0` → всегда `Valid`, `value=radius>0`; детерминированного пост-Add сбоя нет), код отката
структурно идентичен протестированному угловому (коллинеарный путь, счётчик не меняется).
## Правки по ревью Codex (спек)
@@ -149,8 +166,8 @@ RCW точечно не освобождаем (консистентно с ли
5. **Измеряет 90°**: вершина(0,0), (10,0)&(0,10), x3/y3=(5,5) → `Value ≈ 90`.
6. **Измеряет 45°**: вершина(0,0), (10,0)&(10,10), x3/y3=(8,4) → `Value ≈ 45`.
7. **Попадание в вид**: `AngleDimensions.Count` целевого вида +1.
8. **Выбор угла типом** (#2): та же геометрия 90°, но `angleType=More``Value ≈ 270`
(документированное поведение: какой из двух углов измерять, выбирает `angleType`, не `x3,y3`).
8. **Выбор угла типом** (#2): `angleType=More` на геометрии 90° → `Value ≈ 270`; `angleType=Max`
на лучах 0°/45° → `Value ≈ 135` (тупой супплемент). Какой угол измерять, выбирает `angleType`, не `x3,y3`.
9. **Вырожденный угол до Add** (вершина совпадает с точкой стороны) → `ArgumentException`.
10. **Откат после Add** (#3): коллинеарные сонаправленные лучи (0,0),(10,0),(20,0) → угол ≈0 →
`InvalidOperationException`; `AngleDimensions.Count` целевого вида НЕ изменился (откат `Delete`).
@@ -268,11 +268,11 @@ public sealed class DrawingService
throw new InvalidOperationException("Угловой размер построен невалидным.");
var value = ((IDimensionText)dim).NominalValue; // градусы
// Нулевой/некорректный угол — стороны коллинеарны (сонаправлены) или (x3,y3) вне сектора.
// Нулевой/некорректный угол — стороны коллинеарны (лучи сонаправлены → угол вырожден).
if (value <= 0 || !double.IsFinite(value))
throw new InvalidOperationException(
$"Угловой размер измерил некорректное значение ({value}°). Стороны коллинеарны или " +
"положение дуги (x3,y3) задаёт вырожденный сектор.");
$"Угловой размер измерил некорректное значение ({value}°)стороны коллинеарны " +
"(лучи (xc,yc)→(x1,y1) и (xc,yc)→(x2,y2) сонаправлены).");
return new DrawingDimensionResult { Value = value, ViewNumber = view.Number };
}
catch
+1 -1
View File
@@ -117,7 +117,7 @@ public sealed class DrawingTools(KompasSession session, DrawingService drawing)
[Description("Y точки на стороне 1")] double y1,
[Description("X точки на стороне 2")] double x2,
[Description("Y точки на стороне 2")] double y2,
[Description("X положения размерной дуги (внутри измеряемого сектора)")] double x3,
[Description("X положения размерной дуги (отстоит от вершины; угол выбирает angleType, не эта точка)")] double x3,
[Description("Y положения размерной дуги")] double y3,
[Description("Тип угла: min | max | more")] string angleType = "min",
[Description("Номер вида (0 = первый/главный)")] int viewNumber = 0)
@@ -75,6 +75,22 @@ public sealed class DrawingAngularTests : IntegrationTestBase
finally { await _docs.CloseAsync(save: false); }
}
[Fact]
public async Task Angle_type_max_measures_larger_angle()
{
await NewDrawingWithViewsAsync();
try
{
// Лучи 0° и 45°: три типа дают разные углы — min=45 (острый), max=135 (тупой
// супплемент 18045), more=315 (рефлексный). Покрывает маппинг ksADMaxAngle (≠ Min/More).
var r = await _drawing.AddAngularDimensionAsync(
viewNumber: 0, xc: 0, yc: 0, x1: 10, y1: 0, x2: 10, y2: 10, x3: 4, y3: -8,
angleType: AngleDimensionType.Max);
Assert.InRange(r.Value, 134.0, 136.0);
}
finally { await _docs.CloseAsync(save: false); }
}
[Fact]
public async Task Targets_specific_view_and_increments_angular_count()
{