2010-12-27 14 views
8

Krótkie podsumowanie: Pracuję nad opartą na sieci aplikacją do rysowania i muszę narysować grube splajny 1px przechodzące przez ich punkty kontrolne.Rysowanie aliasów, pikselowych splajnów 1px (w szczególności Catmull-Rom)

Problem, z którym zmagam się, polega na tym, że muszę narysować każdy piksel pomiędzy p1 a p2, tak jakbym używał narzędzia ołówkowego 1px. A więc nie ma anty-aliasingu i jednego piksela na raz. Trzeba to zrobić ręcznie, bez użycia jakiegokolwiek kodu biblioteki linii/krzywej, ponieważ mój system szczotek zależy od tego, czy ma się współrzędne pikseli, aby zastosować końcówkę pędzla na płótnie.

Zasadniczo muszę połączyć krok jednego piksela z algorytmem Bresenhama z współrzędnymi zwróconymi przez równanie Catmull-Rom. Mam problem, ponieważ punkty Catmull-Rom nie są równomiernie rozmieszczone (więc nie mogę powiedzieć, że powinno być 100 pikseli na krzywej i uruchomić równanie 100 razy). Próbowałem użyć szacunkowej wartości początkowej maksimum delt X i Y i wypełniając luki Bresenhamem, ale z powodu zaokrągleń nadal kończę z pewnymi "brudnymi" sekcjami (tj. Linia wyraźnie porusza się w górę i do ale wciąż dostaję dwa piksele z tym samym komponentem Y, co skutkuje "grubą" sekcją linii).

Jestem pewien, że zostało to rozwiązane, ponieważ prawie każdy program graficzny, który rysuje splajny, musi obsługiwać czyste krzywe pikseli, których szukam. Jednak po dość sporej ilości badań matematycznych jestem nieco zdezorientowany i wciąż bez rozwiązania. Jakakolwiek rada?

EDIT: Oto przykład krzywej, że mogę mieć do renderowania:

alt text

co mogło oczekiwany rezultat wygląda tak (zauważ, że jest to oszacowanie):

alt text

Stosując równanie splajnu Catmull-Rom potrzebujemy czterech punktów do utworzenia segmentu. P0 i P3 są używane jako styczne do kierunku przychodzącego i wychodzącego z segmentu P1-> P2. W przypadku splajnu Catmull-Rom, sekcja niebieska jest wszystkim, co zostaje interpolowane, gdy t przesuwa się z 0 na 1. P0 i P3 mogą być duplikowane, aby zapewnić, że zielona część zostanie wyrenderowana, więc nie stanowi to dla mnie problemu.

Dla uproszczenia, muszę renderować piksele na łuku między P1 i P2, biorąc pod uwagę, że mam styczne w postaci P0 i P3. Nie koniecznie muszę używać splajnów Catmull-Rom, ale wydaje się, że są one właściwym narzędziem do tego zadania, ponieważ punkty kontrolne muszą zostać przejęte. Nierównomierny rozkład punktów interpolacji jest tym, co rzuca mnie na pętlę.

EDIT2: Oto przykład tego, co mam na myśli, kiedy mówię, moja Powstała krzywa jest brudna:

alt text

Red Arrows zwrócić uwagę na kilka miejsc, w których nie powinno być piksel. Dzieje się tak, ponieważ komponenty X i Y współrzędnych, które są obliczane, nie zmieniają się w tym samym tempie. Tak więc, gdy każdy z komponentów zostanie zaokrąglony (więc mam dokładną lokalizację pikseli), może się zdarzyć, że albo X, albo Y nie zostaną poderwane, ponieważ obliczona współrzędna wynosi, powiedzmy, (42,4999, 50,98). Zamiana rundy na podłogę lub sufit nie rozwiązuje problemu, ponieważ zmienia się tylko tam, gdzie się pojawia.

+0

Byłoby wspaniale, gdybyś mógł dodać kolejny rysunek pokazujący oczekiwany rezultat od P1 do P2. –

+0

@belisarius Nie wyliczyłem matematyki, dla której zostaną wypełnione piksele w oparciu o równanie Catmull-Rom, ale drugi obraz powinien dać ci wyobrażenie o tym, co próbuję osiągnąć. – Xenethyl

+0

Poprosiłem o to ze względu na twój komentarz: _ ale nadal mam dwa piksele z tym samym Y component_ –

Odpowiedz

2

Tutaj masz a paper describing method for the re-parametrization of splines, aby uzyskać równo rozmieszczone punkty wzdłuż długości krzywej.Myślę, że to rozwiąże twój problem, jeśli potrafisz go dostosować do krzywych Catmull-Rom (chyba nie będzie to zbyt trudne, jak sądzę).

+0

Dzięki za link do papieru. W moim Google nie uwzględniłem "długości łuku". Poszukałem trochę więcej wyników i uzyskałem znacznie lepsze wyniki (zobacz http://www.actionscript.org/forums/showthread.php3?t=213252). Wydaje się, że przyjęte rozwiązanie tego problemu zależy od przybliżenia i wstępnego obliczenia. Może to stanowić dla mnie problem z wydajnością, ponieważ odbywa się to w JavaScript. Mogę ponownie opublikować mój problem inaczej po tym, jak to przemyślałem, ale na razie dziękuję za pomoc. Z pewnością wskazałeś mi właściwy kierunek. – Xenethyl

+0

@Xenethyl Glad to help! Mam nadzieję, że zoptymalizujesz to do swojego scenariusza. –

Powiązane problemy