» »

Freehand v krivuljo - C# ali VB

Freehand v krivuljo - C# ali VB

mih3cc ::

V polju tipa System.Drawing.Point imam zapisane koordinate točk, ki sem jih narisal s prosto roko - nekaj takšnega kot svinčnik v slikarju. Sedaj pa bi to zadevo rad nekako pretvoril v krivuljo, brez ostrih robov in tega...nimam pojma kako bi se lotil, tudi na netu ne piše veliko o tem, kolikor sem jaz gledal.

Delam pa v Visual Basicu, prav pa bi mi prišla tudi kakšna koda v C sharpu.
Hvala

WarpedGone ::

Hja, na pamet mi pade Houghov transform.
Zbogom in hvala za vse ribe

mih3cc ::

Hm, sem si prebral tole. Kako pa to izpade v praksi, a moram te točke v polju potem preračunat, in jih vpisat v drugo polje (drugo polje potem vsebuje točke za krivuljo)?

WarpedGone ::

Ne, ideja tega je, da iščeš določen tip lika al pa krivulje v vhodni sliki.
Recimo, da iščeš ravne črte katere predstaviš recimo s točko in kotom. Določiš intervale možnih vrednosti za točke in kote in nato za vse možne vrednosti teh parametrov preveriš al maš v sliki kakšno točko, ki ustreza črti katero določa nek nabor vrednosti. Če ja, to zabeležiš. To ponoviš za vse možne vrednosti parametrov. Vrednosti parametrov, ki so tako dobile "največ glasov" predstavljajo parametre črt v sliki. Mal kontraintuitivno dokler ne probaš. Pa precej računsko zahtevno. Pa precej štorasto za karkoli mal bol kompleksnega.
Zbogom in hvala za vse ribe

mih3cc ::

V bistvu te točke, ki jih imam v polju niso ločene, ampak so na gosto razporejene, tako da tvorijo neko (neravno) črto.

Zgornji postopek pa mislim da bi prav prišel, če bi imel točke ločene, recimo kot na nekakšnem grafu, če se ne motim?

PaX_MaN ::

Ti želiš iz podanih koordinat točk izračunat krivuljo, ki pa mora pod nujno iti skozi vse točke in biti kolikor toliko "okrogla", je tako?
Če je, potem glej za krivuljo Catmull-Rom. Tule je še applet, ki pokaže, kako to zgleda pri dodajanju/brisanju/premikanju točk v živo.

WarpedGone ::

Ne, rezultat je celo boljši, če maš več točk. Število glasov za "pravilne vrednosti" parametrov toliko bolj odstopa od "napačnih vrednosti". Praviš, da bi stvar rad pretvoril v krivuljo. Si se že odločil kašnega tipa krivulja bo to?
Zbogom in hvala za vse ribe

mih3cc ::

Da bo bolj jasno:

Slika pred pretvorbo in želja:

PaX_MaN ::

Vzameš krivuljo Catmull-Rom, samo da za kontrolne točke vzameš vsako N-to, kjer je N poljubno visok?

mih3cc ::

Am, če priznam nimam pojma :D
Lahko malce bolj natančno opišeš?

PaX_MaN ::

Catmull-Rom krivulja vzame štiri kontrolne točke, iz katerih lahko izračunaš vmesne točke po podani funkciji q(t), s povezave, ki sem jo podal zgoraj. Argument t funkcije q, določa, na kateri razdalji med srednjima kontrolnima točkama je. Le-ta teče od 0 do 1. Dodatno je še en parameter (v enačbi 0.5), ki nadzoruje zavitost - s tem se lahko poigraš sam.

Ti imaš v seznamu točk dosti števil, ki si sledijo po vrsti (tako dela slikar...). Hočeš dobiti čimlepšo krivuljo, ki bo opisala nastale podatke. Vzeti vsakič po štiri sosednje točke je malo neumno, saj ne bo krivulja nič lepša, ker so točke že tako ali tako blizu skupaj, in obljenje ne bi imelo učinka.

Zato raje vzameš nek količnik med točkami - točk je N, vzameš pa vsako deseto, dvajseto, petdeseto; venomer po štiri.

Pesvdokoda bi bila nekaj takega:

Point a, b, c,d;#začasne spremenljivke točk
PointArray tocke;#končne točke
int razmik = N/50;#razmik med točkami

for(int i=0; i < (N-3*razmik); i+=razmik) # ker vsakič vzamemo po štiri točke, se moramo ustaviti tri točke pred koncem
{
#vzamemo štiri točke
a =Point( zacetne_tocke[i].x,zacetne_tocke[i].y);
#en razmik naprej
b =Point( zacetne_tocke[i+razmik].x,zacetne_tocke[i+razmik].y);
#dva razmika naprej
c =Point( zacetne_tocke[i+2*razmik].x,zacetne_tocke[i+2*razmik].y);
#tri razmike naprej
d =Point( zacetne_tocke[i+3*razmik].x,zacetne_tocke[i+3*razmik].y);

float t = 0; #argument funkcije t - gre od 0 do 1

#izračunamo vmesne točke
while(t [manjše ali enako od] 1)
{
#izračunaj koordinate točke na mestu t med srednjima točkama
xi = (0.5*((2*b.x)+(c.x-a.x)*0.5+(2*a.x-5*b.x+4*c.x-d.x)*0.5*0.5+(3*b.x-a.x-3*c.x+d.x)*0.5*0.5*0.5));
yi = (0.5*((2*b.y)+(c.y-a.y)*0.5+(2*a.y-5*b.y+4*c.y-d.y)*0.5*0.5+(3*b.y-a.y-3*c.y+d.y)*0.5*0.5*0.5));
#dodaj točko k končnim točkam
tocke.add(Point(xi,yi));
#povečaj argument za poljubno majhno številko
t += 0.005;
}
}
#nariši izračunane točke


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Imam matematični problem

Oddelek: Šola
7741 (585) Boobiz
»

Mi lahko kdo razlozi ta graf?

Oddelek: Šola
302845 (1424) BorutK-73
»

Matematika - pomoč (strani: 1 2 3 )

Oddelek: Šola
10426734 (23309) daisy22
»

[C/C++] Konveksna lupina - brute force

Oddelek: Programiranje
71893 (1767) WarpedGone
»

Collision detection

Oddelek: Programiranje
81909 (1661) Senitel

Več podobnih tem