Files
kniip/.cursor/plans/gebogen_lijnen_e6c44304.plan.md
T
2026-11-09 17:06:35 +01:00

3.9 KiB

name, overview, todos, isProject
name overview todos isProject
Gebogen lijnen Lijnen en pijlen krijgen buigpunten waardoor een vloeiende kromme door alle punten loopt. Bij een geselecteerde lijn staat tussen elk paar punten een spook-greep; slepen daarvan maakt een nieuw buigpunt, dubbelklikken op een buigpunt verwijdert het.
id content status
model LineAnnotation: Bends-lijst, Catmull-Rom-naar-Bezier helper, Render/Bounds/HitTest/Move/Clone aanpassen, pijlpunt langs raaklijn completed
id content status
handles Grepen: buigpunten + spook-grepen, BeginHandleDrag voegt buigpunt in, RemoveHandle; IsGhostHandle/RemoveHandle in Annotation completed
id content status
surface AnnotationSurface: spook-grepen anders tekenen, echte grepen voorrang bij HitHandle completed
id content status
editor EditorWindow: dubbelklik op buigpunt verwijdert het (met undo), hint-tekst bijwerken completed
false

Gebogen lijnen en pijlen

Gedrag

  • Selecteer een lijn of pijl: je ziet de begin- en eindgreep, de buigpunten en, halverwege elk stuk van de kromme, een kleine halfdoorzichtige spook-greep.
  • Sleep je een spook-greep, dan wordt die een echt buigpunt en volgt de lijn de muis (zoals in je screenshot).
  • Dubbelklik op een buigpunt verwijdert het. Beide acties kun je ongedaan maken.
  • De kromme loopt precies door alle punten (Catmull-Rom, omgezet naar kubische Beziers). De pijlpunt volgt de richting van het laatste stuk.

Wijzigingen

src/Kniip/Editor/Annotations/LineAnnotation.cs

  • Nieuw: List<Point> Bends, met Start + Bends + End als doorlooppunten.
  • Een helper bouwt de Bezier-segmenten. Voor Bounds, HitTest en de posities van de spook-grepen gebruikt hij bemonsterde punten (ongeveer 16 per segment). Zonder buigpunten blijft alles gelijk aan nu.
  • Render: een StreamGeometry met BezierTo. Bij een pijl wordt de richting bepaald door End min het laatste controlepunt. Het laatste segment eindigt op het basispunt van de pijlpunt.
  • Grepen: index 0 is Start en 1 is End, zodat bestaande code blijft werken. Daarna volgen de buigpunten en dan de spook-grepen (het Bezier-punt bij t=0,5 van elk segment).
  • BeginHandleDrag: bij een spook-greep wordt een buigpunt op de juiste plek in Bends ingevoegd en het actieve buigpunt onthouden. MoveHandle verplaatst daarna dat punt.
  • Met Shift blijft SnapAngle werken voor begin en eind, maar dan ten opzichte van het naastliggende punt.
  • Move verschuift ook alle buigpunten. Clone maakt een diepe kopie van Bends, nodig voor ongedaan maken (zelfde patroon als in HighlightAnnotation).

src/Kniip/Editor/Annotations/Annotation.cs

  • public virtual bool IsGhostHandle(int index) => false;
  • public virtual bool RemoveHandle(int index) => false; (LineAnnotation verwijdert hiermee een buigpunt)

src/Kniip/Editor/AnnotationSurface.cs

  • DrawSelection tekent spook-grepen als kleinere, halfdoorzichtige cirkels. HitHandle controleert eerst de echte grepen en daarna pas de spook-grepen, zodat een echte greep voorrang krijgt als ze overlappen.

src/Kniip/Editor/EditorWindow.xaml.cs (rond regel 452)

  • In Surface_MouseLeftButtonDown: als op een greep geklikt wordt met e.ClickCount == 2 en _selected.RemoveHandle(handle) slaagt, dan volgen Commit(_pending) en InvalidateVisual, en stopt de verwerking daar. Anders start het bestaande sleepgedrag.
  • Optioneel: in UpdateHint een korte tip toevoegen voor lijnen ("Sleep het middenpunt om te buigen, dubbelklik om een punt te verwijderen").

Niet nodig

Exporteren gaat via Render in src/Kniip/Editor/DocumentRenderer.cs en werkt dus automatisch. Ook het aanmaken van lijnen (UpdateCreating) blijft ongewijzigd: nieuwe lijnen zijn recht.