.[ ČeskéHry.cz ].
Algoritmus pre kreslenie elipsy
Jdi na stránku 1, 2  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Obecné
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 25. srpen 2015, 18:27:40    Předmět: Algoritmus pre kreslenie elipsy Odpovědět s citátem

Dobrý deň všetkým,
programujem teraz algorimus pre kreslenie elipsy no niekde v ňom mám chybu. Beriem aké koľvek komentáre ohladne môjho riešenia. Tu je kód:
kód:

public void DrawEllipse(int a,int b)
    {
       int x = 0;
       int y = b;
       int d = (b*b)-(a*a*b)+(a*a/4);
       DrawEllipsePoint(x, y, Color.red);
       while((a*a)*(y-(1/2)) > (b*b)*(x+1))
       {
           if(d < 0)
           {
               d = d + (b*b)*(2*x+3);
               x = x + 1;
           }
           else
           {
               d = d + (b*b)*(2*x+3)+(a*a)*(2-2*y);
               x = x + 1;
               y = y - 1;
           }
           DrawEllipsePoint(x, y, Color.red);
       }
       d = (b*b)*((x + (1/2)*(x + (1/2)))) + ((a*a)*((y-1)*(y-1))) - ((a*a)*(b*b));
       while(y > 0)
       {
           if(d < 0)
           {
              d = d + (b*b)*(2*x+2)+(a*a)*(3-2*y);
              x = x +1;
              y = y - 1;
           }
           else
           {
               d = d + (a*a)*(3-2*y);
               y = y - 1;
           }
           DrawEllipsePoint(x, y, Color.red);
       }
    }

Procedúra DrawEllipsePoint vyzerá takto:
kód:

private void DrawEllipsePoint(int x,int y, Color c)
    {
        int x0 = (int)ellipse.getX() + (int)(ellipse.getWidth()/2);
        int y0 = (int)ellipse.getY() + (int)(ellipse.getHeight()/2);
        cells[x0+x][y+y0] = new JCanvasCell(JMyCellType.Line, Color.red);
        cells[x0-x][y+y0] = new JCanvasCell(JMyCellType.Line, Color.red);
        cells[x0+x][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
        cells[x0-x][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
    }

Kreslí mi to toto:

Vie mi prosím niekto skontrolovať tento kód a napísať kde by mohla byť chyba ?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 608

PříspěvekZaslal: 25. srpen 2015, 18:37:09    Předmět: Re: Algoritmus pre kreslenie elipsy Odpovědět s citátem

Nevím co to je za algoritmus (co zkusit Bresenhama),
ale poznámka bokem: (1/2) je snad 0 ne? nemyslím, že by to v Javě bylo jinak

EDIT: alternativně, proč nepoužít jednoduše dynamickou teselaci podle poloměrů a nevykreslit to jako polyline? čáry už máš hotové, sice to možná nebude vypadat tak dobře, ale budeš to pak moct kreslit i různě transformované
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 25. srpen 2015, 19:33:06    Předmět: Odpovědět s citátem

Ok. Skúsil som toho Bresenhama. Vyzerá to takto:

kód:

public void DrawEllipase(int x0,int y0,int a, int b)
{   
    /*
    -->    int a = (int)ellipse.getWidth()/2;
    -->    int b = (int)ellipse.getHeight()/2;
    -->    int x0 = (int)ellipse.getX()+ (int)(ellipse.getWidth()/2);
    -->    int y0 = (int)ellipse.getY()+(int)(ellipse.getHeight()/2);;
    */
        if (a == 0 || b == 0)
            return;
         a = Math.abs(a);
         b = Math.abs(b);
         int a2 = 2*a * a;
         int b2 = 2*b * b;
         int error = a*a*b;
         int x = 0;
         int y = b;
         int stopy = 0;
         int stopx = a2 * b ;
         while (stopy <= stopx) {
            cells[x0+x][y0+y] = new JCanvasCell(JMyCellType.Line, Color.red);
            cells[x0-x][y0+y] = new JCanvasCell(JMyCellType.Line, Color.red);
            cells[x0-x][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
            cells[x0+x][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
            ++x;
            error -= b2 * (x - 1);
            stopy += b2;
            if (error <= 0) {
               error += a2 * (y - 1);
               --y;
               stopx -= a2;
            }
         }
         
         error = b*b*a;
         x = a;
         y = 0;
         stopy = b2*a;
         stopx = 0;
         while (stopy >= stopx) {
            cells[x0+x][y0+y] = new JCanvasCell(JMyCellType.Line, Color.red);
            cells[x0-x][y0+y] = new JCanvasCell(JMyCellType.Line, Color.red);
            cells[x0-x][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
            cells[x0+x][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
            ++y;
            error -= a2 * (y - 1);
            stopx += a2;
            if (error < 0) {
               error += b2 * (x - 1);
               --x;
               stopy -= b2;
            }
    }
}

Dobré je na tom že to funguje. Komu to pomôže nech si to pozrie a použije niekde. Zatial ďakujem.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 25. srpen 2015, 21:21:51    Předmět: Odpovědět s citátem

Ešte otázka. Ako by sa dala hrúbka čiary kružnice rozšíriť o bod alebo viac ? Teda stačí nastaviť x0 = x0 + hrubka; y0 = y0 + hrubka; a = a - hrubka; b = b - hrubka; a znovu vykresliť ešte jednu hružnicu a tým dostanem jednu hrubú alebo iný postup ?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 608

PříspěvekZaslal: 25. srpen 2015, 21:38:46    Předmět: Odpovědět s citátem

No myslím, že kreslit n kružnic s jinými poloměry ti nemusí na sebe sedět (tj. sem tam ti vypadne bod).
Pokud ti nezáleží na výkonu, můžeš jednoduše kreslit tlustší body.
Možná by nemuselo vypadat špatně ani jednoduché horiz/vert. rozšíření (jedna smyčka kreslí ve směru x, takže tady kreslit body y+-n, druhá ve směru y, tady x+-n).
tím y+-n samozřejmě myslím finální pozici y pro všechny čtyři body

EDIT: tak na tu druhou možnost zapomeň, tam by byly zuby na přechodech. nejjednodušší bude kreslit tlustší body
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 26. srpen 2015, 14:59:42    Předmět: Odpovědět s citátem

Niečo takéto asi správne nebude ?
kód:

while (stopy >= stopx) {
         for(int n = 0; n < hrubkaCiary;n++) // hrubkaCiary >= 1
                       {
              cells[x0+x+n][y0+y+n] = new JCanvasCell(JMyCellType.Line, Color.red);
              cells[x0-x-n][y0+y+n] = new JCanvasCell(JMyCellType.Line, Color.red);
              cells[x0-x-n][y0-y-n] = new JCanvasCell(JMyCellType.Line, Color.red);
              cells[x0+x+n][y0-y-n] = new JCanvasCell(JMyCellType.Line, Color.red);
                                }

Ako by to malo vyzerať aby bola čiara hrubšia v pixeloch ?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 26. srpen 2015, 20:09:37    Předmět: Odpovědět s citátem

Zapísal som to kreslenie elipsy takto:
kód:

while (stopy <= stopx) {
                               
                               for(int n = 0;n < sirka / 2;n++)
                               {
                                cells[x0+x-n][y0+y] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0+x+n][y0+y] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0+x][y0+y-n] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0+x][y0+y+n] = new JCanvasCell(JMyCellType.Line, Color.red);
            
                                cells[x0-x-n][y0+y] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0-x+n][y0+y] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0-x][y0+y-n] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0-x][y0+y+n] = new JCanvasCell(JMyCellType.Line, Color.red);
                               
                                cells[x0-x-n][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0-x+n][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0-x][y0-y-n] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0-x][y0-y+n] = new JCanvasCell(JMyCellType.Line, Color.red);
                               
                                cells[x0+x-n][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0+x+n][y0-y] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0+x][y0-y-n] = new JCanvasCell(JMyCellType.Line, Color.red);
                                cells[x0+x][y0-y+n] = new JCanvasCell(JMyCellType.Line, Color.red);
                               }
                                   ..........................atď..............................

Výsledok so šírkou 10 vyzerá takto:

Keď že jedno opakovanie pridá na každú os 2px tak n < šírka / 2 to je počet opakovaní čiže do plusu 4 aj do mínusu 4 na osiach X,Y a jeden pixel vstrede = 10.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 608

PříspěvekZaslal: 26. srpen 2015, 20:39:04    Předmět: Odpovědět s citátem

No jak vidíš tohle je ta "druhá" možnost a moc kulatě to nevypadá (viz vpravo dole).
Takže bych to asi rozbil do víc funkcí a kreslil bych větší celé pixely (stejně máš heavyweight object per pixel takže o výkonu nemá smysl se vůbec bavit)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 26. srpen 2015, 21:18:25    Předmět: Odpovědět s citátem

No mne to ide na mojom počítači v pohode a mislím že to pojde v pohode aj inde tak túto vec neriešim. Chcem len aby to vôbec išlo a zatial to ide len tak z polovice dobre. musím na tom ešte troško popracovať.

EDIT: To prvé v pohode som myslel tak že čo sa týka rýchlosti tak to ide v pohode. To druhé z polovice dobre sa týka algorimov.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 28. srpen 2015, 21:44:44    Předmět: Odpovědět s citátem

No premýšlam nad tým kresliť večšie pixely. Programujem to celé v Jave a kreslím najskor do BufferedImage objektu. Tam volám metódu myBuffImage.setRGB(int x, int y, int rgbColor). No problém mám ako spraviť večší pixel keď fyzicky pracujem asi s najmänším možným bodom. Teda mám nakresliť štvorec s 2x2 pixelmy aby som mal väčšiu hrúbku čiary ? Čo bude najlepšie riešenie ?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 29. srpen 2015, 07:41:51    Předmět: Odpovědět s citátem

Mě tak trochu zajímá, když používáš BufferedImage, proč to nekreslíš pomocí metod, které jsou v Graphics...
Je tam metoda drawOval/fillOval, která bude rozhodně mnohem rychlejší, než když to kreslíš přes setRGB.
Navíc můžeš pomocí třídy Stroke měnit jak bude čára tlustá, atp.

kód:
Graphics2D g = image.createGraphics();
g.drawOval(...);

_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 30. srpen 2015, 14:39:25    Předmět: Odpovědět s citátem

Kreslenie som robil najskor cez Graphics2D objekt len som potreboval nejak ulozit ze kde je vypln(brush), kde ciara(line) a kde nieje nic. Vytvoril som si preto maticu o velkosti kresliaceho platna a do nej som zapisoval na ktorych bodoch sa co nachádza. potom som maticu presiel v slucke v metode Render() a dane body som zakreslil do bufferedImage objektu. Ked Potrebujem vyplnit danú oblast nejakou farbou tak si vzdy kontrolujem ze ci dany bod nie je na ciare a ked je tak tam vypln skoncim. samotná trieda BufferedImage take moznosti nema. Problem mam teraz v tom ze ako zakreslim a zapisem vecsi pixel.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 3. září 2015, 16:54:32    Předmět: Odpovědět s citátem

To mi to nikto nevie odpovedať, alebo nechce lebo ja by som to dosť potreboval. Premýšlal som nad tým nakresliť z každého bodu čiaru o určitej dlžke a tým spraviť hrubšiu čiaru.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1047

PříspěvekZaslal: 3. září 2015, 17:38:24    Předmět: Odpovědět s citátem

Mozno nie najefektivnejsi algoritmus ale ja by som pre kazdy pixel vyratal ci lezi medzi dvoma elipsami vyjadrene parametricky.
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jefo



Založen: 02. 07. 2011
Příspěvky: 58

PříspěvekZaslal: 3. září 2015, 19:26:54    Předmět: Odpovědět s citátem

Myslím že to je celkom dobré riešenie. V podstate by na to stačila upravená procedúra s Flood Fill Algoritmom na vyplnenie všetkých pixelov medzi elipsamy. Teda nakreslnenie dvoch kružníc a potom vyplnenie priestoru medzi nimi.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Obecné Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna