Interpolacja kolorów w trójkącie

0

Witam.

Mam problem przy interpolacji kolorów z wierzchołków na cały trójkąt.
Prawa krawędź jest "poszarpana".
Czy ktoś dopatrzył się może jakiegoś błędu, który powoduje nieprawidłowe wypełnienie trójkąta?

Oto kod z przykładem działania:

public static void drawTriangle(BufferedImage image,int p1X,int p1Y,int p2X,int p2Y,int p3X,int p3Y,Color a,Color b, Color c, int ox, int oy)
    {
        if(a.equals(b) && b.equals(c))
        {
            Polygon pol = new Polygon();
            pol.addPoint(p1X, p1Y);
            pol.addPoint(p2X, p2Y);
            pol.addPoint(p3X, p3Y);
            Graphics2D g2d = (Graphics2D)image.getGraphics();
            g2d.setColor(a);
            g2d.fillPolygon(pol);
        }
        else
        {
        float p1x,p1y,p2x,p2y,p3x,p3y;//współrzedne wierzcholków
        Color c1,c2,c3;//kolory w wierzchołkach
        float dx1,dx2,dx3;//delty używane przy interpolacji x-ów
        float dr1,dr2,dr3, dg1,dg2,dg3, db1,db2,db3;//delty używane przy interpolacji kolorów

        float c1r,c2r,c3r,c1g,c2g,c3g,c1b,c2b,c3b;
        float scr,scg,scb,ecr,ecg,ecb;
        c1r=c2r=c3r=c1g=c2g=c3g=c1b=c2b=c3b=0;
        scr=scg=scb=ecr=ecg=ecb=0;
        c1 = c2 = c3 = null;
        p1x=p1y=p2x=p2y=p3x=p3y=0;
        dx1=dx2=dx3=0;
        dr1=dr2=dr3=dg1=dg2=dg3=db1=db2=db3=0;
        float dr,dg,db;
        dr = dg = db = 0;

        float sx,sy,ex,ey;
        Color sc, ec;
        sc=ec=null;
        sx=sy=ex=ey = 0;

        float px = 0;
        float py = 0;
        Color pc = null;
        float pcr,pcg,pcb;
        pcr=pcg=pcb=0;
        //sortowanie p1y <= p2y <= p3y
        if(p1Y <= p2Y)
        {
            if(p2Y <= p3Y)
            {
                p1x = p1X;
                p1y = p1Y;
                p2x = p2X;
                p2y = p2Y;
                p3x = p3X;
                p3y = p3Y;
                c1r=a.getRed();
                c2r=b.getRed();
                c3r=c.getRed();
                c1g=a.getGreen();
                c2g=b.getGreen();
                c3g=c.getGreen();
                c1b=a.getBlue();
                c2b=b.getBlue();
                c3b=c.getBlue();
                /*
                c1 = a;
                c2 = b;
                c3 = c;
                */
            }
            else
            {
                p1x = p1X;
                p1y = p1Y;
                p2x = p3X;
                p2y = p3Y;
                p3x = p2X;
                p3y = p2Y;
                /*
                c1 = a;
                c2 = c;
                c3 = b;
                */
                c1r=a.getRed();
                c2r=c.getRed();
                c3r=b.getRed();
                c1g=a.getGreen();
                c2g=c.getGreen();
                c3g=b.getGreen();
                c1b=a.getBlue();
                c2b=c.getBlue();
                c3b=b.getBlue();
            }
        }
        else if(p2Y<=p1Y)
        {
            if(p1Y <= p3Y)
            {
                p1x = p2X;
                p1y = p2Y;
                p2x = p1X;
                p2y = p1Y;
                p3x = p3X;
                p3y = p3Y;
                /*
                c1 = b;
                c2 = a;
                c3 = c;
                */
                c1r=b.getRed();
                c2r=a.getRed();
                c3r=c.getRed();
                c1g=b.getGreen();
                c2g=a.getGreen();
                c3g=c.getGreen();
                c1b=b.getBlue();
                c2b=a.getBlue();
                c3b=c.getBlue();
            }
            else
            {
                p1x = p2X;
                p1y = p2Y;
                p2x = p3X;
                p2y = p3Y;
                p3x = p1X;
                p3y = p1Y;
                /*
                c1 = b;
                c2 = c;
                c3 = a;
                */
                c1r=b.getRed();
                c2r=c.getRed();
                c3r=a.getRed();
                c1g=b.getGreen();
                c2g=c.getGreen();
                c3g=a.getGreen();
                c1b=b.getBlue();
                c2b=c.getBlue();
                c3b=a.getBlue();
            }
        }
        else if(p3Y <= p1Y)
        {
            if(p1Y <= p2Y)
            {
                p1x = p3X;
                p1y = p3Y;
                p2x = p1X;
                p2y = p1Y;
                p3x = p2X;
                p3y = p2Y;
                /*
                c1 = c;
                c2 = a;
                c3 = b;
                */
                c1r=c.getRed();
                c2r=a.getRed();
                c3r=b.getRed();
                c1g=c.getGreen();
                c2g=a.getGreen();
                c3g=b.getGreen();
                c1b=c.getBlue();
                c2b=a.getBlue();
                c3b=b.getBlue();
            }
            else
            {
                p1x = p3X;
                p1y = p3Y;
                p2x = p2X;
                p2y = p2Y;
                p3x = p1X;
                p3y = p1Y;
                /*
                c1 = c;
                c2 = b;
                c3 = a;
                */
                c1r=c.getRed();
                c2r=b.getRed();
                c3r=a.getRed();
                c1g=c.getGreen();
                c2g=b.getGreen();
                c3g=a.getGreen();
                c1b=c.getBlue();
                c2b=b.getBlue();
                c3b=a.getBlue();
            }
        }

        p1x+=ox;
        p2x+=ox;
        p3x+=ox;
        p1y-=oy;
        p2y-=oy;
        p3y-=oy;

        //wyliczanie delt dla składowych koloru
        if (p2y-p1y > 0) 
        {
            dx1=(p2x-p1x)/(p2y-p1y);
            /*
            dr1=(c2.getRed()-c1.getRed())/(p2y-p1y);
            dg1=(c2.getGreen()-c1.getGreen())/(p2y-p1y);
            db1=(c2.getBlue()-c1.getBlue())/(p2y-p1y);
            */
            dr1=(c2r-c1r)/(p2y-p1y);
            dg1=(c2g-c1g)/(p2y-p1y);
            db1=(c2b-c1b)/(p2y-p1y);
        } 
        else 
            dx1=dr1=dg1=db1=0;

        if (p3y-p1y > 0) 
        {
            dx2=(p3x-p1x)/(p3y-p1y);
            /*
            dr2=(c3.getRed()-c1.getRed())/(p3y-p1y);
            dg2=(c3.getGreen()-c1.getGreen())/(p3y-p1y);
            db2=(c3.getBlue()-c1.getBlue())/(p3y-p1y);
            */
            dr2=(c3r-c1r)/(p3y-p1y);
            dg2=(c3g-c1g)/(p3y-p1y);
            db2=(c3b-c1b)/(p3y-p1y);
        } 
        else 
            dx2=dr2=dg2=db2=0;

        if (p3y-p2y > 0) 
        {
            dx3=(p3x-p2x)/(p3y-p2y);
            /*
            dr3=(c3.getRed()-c2.getRed())/(p3y-p2y);
            dg3=(c3.getGreen()-c2.getGreen())/(p3y-p2y);
            db3=(c3.getBlue()-c2.getBlue())/(p3y-p2y);
            */
            dr3=(c3r-c2r)/(p3y-p2y);
            dg3=(c3g-c2g)/(p3y-p2y);
            db3=(c3b-c2b)/(p3y-p2y);
        } 
        else 
            dx3=dr3=dg3=db3=0;

        sx = ex = p1x;
        sy = ey = p1y;
        /*
        sc = new Color(c1.getRed(),c1.getGreen(),c1.getBlue());
        ec = new Color(c1.getRed(),c1.getGreen(),c1.getBlue());
        */
        scr=ecr=c1r;
        scg=ecg=c1g;
        scb=ecb=c1b;

        if(dx1 > dx2)
        {
            for(;sy <= p2y;sy++,ey++)
            {
                if(ex-ex > 0) 
                {
                    /*
                    dr=(ec.getRed()-sc.getRed())/(ex-sx);
                    dg=(ec.getGreen()-sc.getGreen())/(ex-sx);
                    db=(ec.getBlue()-sc.getBlue())/(ex-sx);
                    */
                    dr=(ecr-scr)/(ex-sx);
                    dg=(ecg-scg)/(ex-sx);
                    db=(ecb-scb)/(ex-sx);
                } 
                else 
                    dr=dg=db=0;

                px = sx;
                py = sy;
                pcr = scr;
                pcg = scg;
                pcb = scb;

                for(;px < ex;px++) 
                {
                    try{
                        image.setRGB(Math.round(px), Math.round(py), RGBToInt(new Color(Math.round(pcr),Math.round(pcg),Math.round(pcb))));
                    }
                    catch(Exception e)
                    {
                        System.out.println("1");
                    }
                    /*
                    pc = new Color((int)(pc.getRed()+dr),(int)(pc.getGreen()+dg),(int)(pc.getBlue()+db));
                    */
                    pcr+=dr;
                    pcg+=dg;
                    pcb+=db;
                }
                sx+=dx2;
                ex+=dx1;

                /*
                sc = new Color((int)(sc.getRed()+dr2),(int)(sc.getGreen()+dg2),(int)(sc.getBlue()+db2));
                ec = new Color((int)(ec.getRed()+dr1),(int)(ec.getGreen()+dg1),(int)(ec.getBlue()+db1));
                */

                scr+=dr2;
                scg+=dg2;
                scb+=db2;

                ecr+=dr1;
                ecg+=dg1;
                ecb +=db1;

            }

            ex = p2x;
            ey = p2y;
            /*
            ec = new Color(c2.getRed(),c2.getGreen(),c2.getBlue());
            */
            ecr = c2r;
            ecg = c2g;
            ecb = c2b;

            for(;sy<=p3y;sy++,ey++) 
            {
                if(ex-sx > 0) {
                    /*
                    dr=(ec.getRed()-sc.getRed())/(ex-sx);
                    dg=(ec.getGreen()-sc.getGreen())/(ex-sx);
                    db=(ec.getBlue()-sc.getBlue())/(ex-sx);
                    */
                    dr=(ecr-scr)/(ex-sx);
                    dg=(ecg-scg)/(ex-sx);
                    db=(ecb-scb)/(ex-sx);
                } 
                else 
                    dr=dg=db=0;

                px = sx;
                py = sy;
                /*
                pc = new Color(sc.getRed(),sc.getGreen(),sc.getBlue());;
                */
                pcr = scr;
                pcg = scg;
                pcb = scb;

                for(;px < ex;px++) 
                {

                        try
                        {
                            image.setRGB(Math.round(px), Math.round(py), RGBToInt(new Color(Math.round(pcr),Math.round(pcg),Math.round(pcb))));
                        }
                        catch(Exception e)
                        {
                            System.out.println("2");
                        }
                    /*
                    pc = new Color((int)(pc.getRed()+dr),(int)(pc.getGreen()+dg),(int)(pc.getBlue()+db));
                    */
                    pcr+=dr;
                    pcg+=dg;
                    pcb+=db;

                }
                /*
                sx+=dx2; sc = new Color((int)(sc.getRed()+dr2),(int)(sc.getGreen()+dg2),(int)(sc.getBlue()+db2));
                ex+=dx3; ec = new Color((int)(ec.getRed()+dr3),(int)(ec.getGreen()+dg3),(int)(ec.getBlue()+db3));
                */
                sx+=dx2;
                ex+=dx3;

                scr+=dr2;
                scg+=dg2;
                scb+=db2;

                ecr+=dr3;
                ecg+=dg3;
                ecb+=db3;
            }
        }
        else 
        {
            for(;sy<=p2y;sy++,ey++) 
            {

                if(ex-sx > 0) {
                    /*
                    dr=(ec.getRed()-sc.getRed())/(ex-sx);
                    dg=(ec.getGreen()-sc.getGreen())/(ex-sx);
                    db=(ec.getBlue()-sc.getBlue())/(ex-sx);
                    */
                    dr=(ecr-scr)/(ex-sx);
                    dg=(ecg-scg)/(ex-sx);
                    db=(ecb-scb)/(ex-sx);
                } 
                else 
                    dr=dg=db=0;

                px = sx;
                py = sy;
                /*
                pc = new Color(sc.getRed(),sc.getGreen(),sc.getBlue());;
                */
                pcr=scr;;
                pcg=scg;
                pcb=scb;

                for(;px < ex;px++) 
                {

                    try
                    {
                        image.setRGB(Math.round(px), Math.round(py), RGBToInt(new Color(Math.round(pcr),Math.round(pcg),Math.round(pcb))));
                    }
                    catch(Exception e)
                    {
                        System.out.println("3");
                    }
                    /*
                    pc = new Color((int)(pc.getRed()+dr),(int)(pc.getGreen()+dg),(int)(pc.getBlue()+db));
                    */
                    pcr+=dr;
                    pcg+=dg;
                    pcb+=db;

                }
                /*
                sx+=dx1; sc = new Color((int)(sc.getRed()+dr1),(int)(sc.getGreen()+dg1),(int)(sc.getBlue()+db1));
                ex+=dx2; ec = new Color((int)(ec.getRed()+dr2),(int)(ec.getGreen()+dg2),(int)(ec.getBlue()+db2));
                */
                sx+=dx1;
                ex+=dx2;

                scr+=dr1;
                scg+=dg1;
                scb+=db1;

                ecr+=dr2;
                ecg+=dg2;
                ecb+=db2;
            }

            sx = p2x;
            sy = p2y;
            /*
            sc = new Color(c2.getRed(),c2.getGreen(),c2.getBlue());
            */
            scr = c2r;
            scg = c2g;
            scb = c2b;

            for(;sy<=p3y;sy++,ey++) {
                if(ex-sx > 0) {
                    /*
                    dr=(ec.getRed()-sc.getRed())/(ex-sx);
                    dg=(ec.getGreen()-sc.getGreen())/(ex-sx);
                    db=(ec.getBlue()-sc.getBlue())/(ex-sx);
                    */
                    dr=(ecr-scr)/(ex-sx);
                    dg=(ecg-scg)/(ex-sx);
                    db=(ecb-scb)/(ex-sx);
                } 
                else 
                    dr=dg=db=0;

                px = sx;
                py = sy;
                /*
                pc = new Color(sc.getRed(),sc.getGreen(),sc.getBlue());;
                */
                pcr = scr;
                pcg = scg;
                pcb = scb;

                for(;px < ex;px++) {

                    try{
                        image.setRGB(Math.round(px), Math.round(py), RGBToInt(new Color(Math.round(pcr),Math.round(pcg),Math.round(pcb))));
                        }
                        catch(Exception e)
                        {
                            System.out.println("4");
                        }
                    /*
                    pc = new Color((int)(pc.getRed()+dr),(int)(pc.getGreen()+dg),(int)(pc.getBlue()+db));
                    */

                        pcr += dr;

                        pcg+=dg;

                        pcb+=db;

                }
                /*
                sx+=dx3; sc = new Color((int)(sc.getRed()+dr3),(int)(sc.getGreen()+dg3),(int)(sc.getBlue()+db3));
                ex+=dx2; ec = new Color((int)(ec.getRed()+dr2),(int)(ec.getGreen()+dg2),(int)(ec.getBlue()+db2));'
                */
                sx+=dx3;
                ex+=dx2;

                scr+=dr3;
                scg+=dg3;
                scb+=db3;

                ecr+=dr2;
                ecg+=dg2;
                ecb+=db2;
            }
        }
        }
    }
<image>http://fotoo.pl/show.php/4739[...]p.html"]przykład</image&gt;
0

Strasznie zagmatwany ten kod i ciężko się to czyta strasznie. Obstawiał bym jednak, że winny jest brak ustawionego anty aliasingu przy tworzeniu i/lub wyświetlaniu obrazka.

g2.setRenderingHints(RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON);
0

Faktycznie kod trochę zagmatwany, ale problem udało mi się rozwiązać.
Zostaje tylko jeden problem: nie rysuje trójkątów obróconych o 180 st.
tj. user image

Zamieszczam pseudokod aby ułatwić zrozumienie problemu:


the coordinates of vertices are (A.x,A.y), (B.x,B.y), (C.x,C.y) we assume that A.y<=B.y<=C.y (you should sort them first)
vertex A has color (A.r,A.g,A.b), B (B.r,B.g,B.b), C (C.r,C.g,C.b), where X.r is color's red component, X.g is color's green component and X.b is color's blue component
dx1,dx2,dx3 are deltas used in interpolation of x-coordinate
dr1,dr2,dr3, dg1,dg2,dg3, db1,db2,db3 are deltas used in interpolation of color's components
putpixel(P) plots a pixel with coordinates (P.x,P.y) and color (P.r,P.g,P.b)
S=A means that S.x=A.x; S.y=A.y; S.r=A.r; S.g=A.g; S.b=A.b;
*** begin gouraud triangle filler ***

    if (B.y-A.y > 0) {
        dx1=(B.x-A.x)/(B.y-A.y);
        dr1=(B.r-A.r)/(B.y-A.y);
        dg1=(B.g-A.g)/(B.y-A.y);
        db1=(B.b-A.b)/(B.y-A.y);
    } else 
        dx1=dr1=dg1=db1=0;

    if (C.y-A.y > 0) {
        dx2=(C.x-A.x)/(C.y-A.y);
        dr2=(C.r-A.r)/(C.y-A.y);
        dg2=(C.g-A.g)/(C.y-A.y);
        db2=(C.b-A.b)/(C.y-A.y);
    } else 
        dx2=dr2=dg2=db2=0;

    if (C.y-B.y > 0) {
        dx3=(C.x-B.x)/(C.y-B.y);
        dr3=(C.r-B.r)/(C.y-B.y);
        dg3=(C.g-B.g)/(C.y-B.y);
        db3=(C.b-B.b)/(C.y-B.y);
    } else 
        dx3=dr3=dg3=db3=0;

    S=E=A;
    if(dx1 > dx2) {
        for(;S.y<=B.y;S.y++,E.y++) {
            if(E.x-S.x > 0) {
                dr=(E.r-S.r)/(E.x-S.x);
                dg=(E.g-S.g)/(E.x-S.x);
                db=(E.b-S.b)/(E.x-S.x);
            } else 
                dr=dg=db=0;
            P=S;
            for(;P.x < E.x;P.x++) {
                putpixel(P);
                P.r+=dr; P.g+=dg; P.b+=db;
            }
            S.x+=dx2; S.r+=dr2; S.g+=dg2; S.b+=db2;
            E.x+=dx1; E.r+=dr1; E.g+=dg1; E.b+=db1;
        }

        E=B;
        for(;S.y<=C.y;S.y++,E.y++) {
            if(E.x-S.x > 0) {
                dr=(E.r-S.r)/(E.x-S.x);
                dg=(E.g-S.g)/(E.x-S.x);
                db=(E.b-S.b)/(E.x-S.x);
            } else 
                dr=dg=db=0;
            P=S;
            for(;P.x < E.x;P.x++) {
                putpixel(P);
                P.r+=dr; P.g+=dg; P.b+=db;
            }
            S.x+=dx2; S.r+=dr2; S.g+=dg2; S.b+=db2;
            E.x+=dx3; E.r+=dr3; E.g+=dg3; E.b+=db3;
        }
    } else {
        for(;S.y<=B.y;S.y++,E.y++) {
            if(E.x-S.x > 0) {
                dr=(E.r-S.r)/(E.x-S.x);
                dg=(E.g-S.g)/(E.x-S.x);
                db=(E.b-S.b)/(E.x-S.x);
            } else 
                dr=dg=db=0;

            P=S;
            for(;P.x < E.x;P.x++) {
                putpixel(P);
                P.r+=dr; P.g+=dg; P.b+=db;
            }
            S.x+=dx1; S.r+=dr1; S.g+=dg1; S.b+=db1;
            E.x+=dx2; E.r+=dr2; E.g+=dg2; E.b+=db2;
        }

        S=B;
        for(;S.y<=C.y;S.y++,E.y++) {
            if(E.x-S.x > 0) {
                dr=(E.r-S.r)/(E.x-S.x);
                dg=(E.g-S.g)/(E.x-S.x);
                db=(E.b-S.b)/(E.x-S.x);
            } else 
                dr=dg=db=0;

            P=S;
            for(;P.x < E.x;P.x++) {
                putpixel(P);
                P.r+=dr; P.g+=dg; P.b+=db;
            }
            S.x+=dx3; S.r+=dr3; S.g+=dg3; S.b+=db3;
            E.x+=dx2; E.r+=dr2; E.g+=dg2; E.b+=db2;
        }
    }

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0