Toon posts:

[JAVA]Resizen van een polygon

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo, voor een project ben ik bezig om een tekenprogramma te maken in java.
Ik gebruik swing en al het tekenwerk gebeurt in een bepaald JPanel.
Alle vormen die men tekent sla ik op in Polygons.
Nu wil ik een resize functie implementeren. Dit heb ik met mousehandlers gedaan die de muiscoordinaten oppikken dus ik ben reeds voorzien van een oude x een oude y en een nieuwe x en y.
Ik teken van de boundingbox in de rechterbovenhoek vierkantje. Als men deze versleept wil ik resizen.

Momenteel bereken ik het centrum(centroid) en aan de hand daarvan bepaal ik hoe er geresized word.
Dit is mijn huidige resize functie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public void resize(int x1, int y1, int x2, int y2, int n)
    {
        int xdif = x2 - x1;
        int ydif = y2 - y1;
        Polygon p = s;
        Point c = new Point(0, 0);

                //Calculate centroid
        for (int i = 0; i < p.npoints; i++)
            c.translate(p.xpoints[i], p.ypoints[i]);
        c.x = c.x / p.npoints;
        c.y = c.y / p.npoints;

        for (int i = 0; i < p.npoints; i++)
        {
            if (p.xpoints[i] <= c.x)
                p.xpoints[i] -= xdif;
            else if (p.xpoints[i] >= c.x)
                p.xpoints[i] += xdif;

            if (p.ypoints[i] <= c.y)
                p.ypoints[i] += ydif;
            else if (p.ypoints[i] >= c.y)
                p.ypoints[i] -= ydif;
        }
    }


Dit werkt in principe best goed voor vierkanten. Maar voor veelhoeken, cirkels(regelmatig 100hoek) etc. krijg ik rare verschijnselen. Heeft iemand een idee hoe dat kan of een idee voor een beter algoritme?

Acties:
  • 0 Henk 'm!

  • Gimmeabrake
  • Registratie: December 2008
  • Laatst online: 06-10 18:04
Ik heb je code niet 100% op fouten gecheckt, maar wat mij opvalt is dat je integer coordinaten gebruikt.

Het zou handig zijn geweest als je wat voorbeelden had getoond wat er bij het resizen mis gaat, maar als je vooral bij het verkleinen problemen hebt, ligt het waarschijnlijk aan die integer coordinaten. Coordinaten gaan gek op elkaar liggen als je verschillen zo klein worden dat ze niet meer in integers uitgedrukt kunnen worden.

Voor Point is er in Java een alternatief met doubles, Point2D.Double. Voor de polygon class is dat er niet, al denk ik dat je met Path2D.Double een heel eind zou moeten kunnen komen.

Je kunt het in ieder geval een keer proberen. ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thnx dat ga ik iig proberen nog niet over nagedacht.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Er klopt niets van je berekening. In een resize verwacht ik een vermenigvuldiging, geen optelling. Als je iets 2x zo groot maakt, dan ligt een punt dat op een bepaalde afstand van een bepaald referentiepunt ligt (zoals je centroid), daarna 2x zo ver. Een punt dat op afstand 10 ligt, ligt daarna dus 10 eenheden verder op afstand 20. Een punt dat op afstand 30 ligt, ligt daarna 30 eenheden verder (en dus niet ook 10 zoals jouw code doet vermoeden) op afstand 60.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
update: ik heb een Polygon2D klasse gevonden en gebruikt. Nu zijn alle punten float. Nog steeds doet het velfde probleem voor:

@.oisyn je moet dus de relatieve afstand tot het centrum vermenigvuldigen met het relatieve verschil in coordinaten?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void resize(int x1, int y1, int x2, int y2, int n)
    {
        float xdif = x2 - x1;
        float ydif = y2 - y1;       
        
        float cx = (float) path.getBounds2D().getCenterX();
        float cy = (float) path.getBounds2D().getCenterY();

        for (int i = 0; i < ((Polygon2D)path).npoints; i++)
        {
            if (((Polygon2D)path).xpoints[i] <= cx)
                ((Polygon2D)path).xpoints[i] -= xdif;
            else if (((Polygon2D)path).xpoints[i] >= cx)
                ((Polygon2D)path).xpoints[i] += xdif;

            if (((Polygon2D)path).ypoints[i] <= cy)
                ((Polygon2D)path).ypoints[i] += ydif;
            else if (((Polygon2D)path).ypoints[i] >= cy)
                ((Polygon2D)path).ypoints[i] -= ydif;
        }
    }

Acties:
  • 0 Henk 'm!

  • Arie-
  • Registratie: December 2008
  • Niet online
Stel voor, centrum ligt op (0,0), punt a ligt op (1,1) en b ligt op (2,2), nu vergroot je het figuur twee keer. Intuïtief weet je dat het centrum dan op (0,0) blijft, a op (2,2) terecht komt en b op (4,4) terecht komt. De afstanden tussen centrum en a, en a en b blijven even groot. In de situatie voor het vergroten is dit sqrt(2) en in situatie daarna is dit sqrt(4). Als je kijkt naar jouw code, bij het vergroten tel je er een getal bij op ipv vermenigvuldigen. Ga je uit van twee keer zo groot, dan worden komt a op (3,3) te liggen, 1+2 is immers 3. B zou bij jou op (4,4) komen te liggen. Hierbij valt ook meteen op dat de afstanden tussen centrum en a, en a en b niet langer gelijk zijn, maar sqrt(9) en sqrt(2).

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op donderdag 31 mei 2012 @ 14:19:
@.oisyn je moet dus de relatieve afstand tot het centrum vermenigvuldigen
klopt
met het relatieve verschil in coordinaten?
Nee, het relatieve verschil in coordinaten gebruik je om een schaalfactor te berekenen. Ik weet niet hoe je huidige code in elkaar zit, maar als je de rechter onderhoek van een box van 100 bij 100 versleept met (+50, +50), dan is hij dus een factor 150 / 100 = 1,5 keer zo groot. Je resize() functie heeft dus niet voldoende parameters, want hij weet niet hoe groot de box was.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Het middelpunt valt wel op te halen omdat de functie in een klasse staat en onder de naam path staat de shape

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void resize(int x1, int y1, int x2, int y2, int n)
    {
        //Middelpunt
        float cx = (float) path.getBounds2D().getCenterX();
        float cy = (float) path.getBounds2D().getCenterY();
        
        float xzoom = (float)(cx-x2) / (float)(cx-x1);
        float yzoom = (float)(cy-y2) / (float)(cy-y1);       
        
        //path is de Shape
        Polygon2D p = (Polygon2D)path;

        for (int i = 0; i < ((Polygon2D)path).npoints; i++)
        {
//VGM is de zoomfactor nu goed maar hoe nu toepassen
        }
    }

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Gewoon het verschil met het centrum vermenigvuldigen met de factor.

Als een punt op x=10 ligt, en cx=5, dan is de afstand tot het centrum natuurlijk 10-5 = 5. Met een factor van 2 wordt die afstand 2x zo groot, dus 10. Dus wat moet x dan worden?

[ Voor 8% gewijzigd door .oisyn op 31-05-2012 16:06 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
x = (x-cx)*2+cx
Maar dit werkt nog steeds niet, er komen rare vormen uit
Dit geld alleen voor punten die rechts onder van centrum liggen Maar dat maakt niet uit als ik maar 1 punt aan de praat krijg...

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nee, dat geldt voor álle punten; links, rechts, boven en onder.

Als x=0 (afstand -5), dan wordt x=-5 (afstand -10)

[ Voor 29% gewijzigd door .oisyn op 31-05-2012 16:42 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
dan nog werkt het niet. Ligt het misschien aan de plaatsing van de punten?
0----->x
|
|
v
y

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nee, de orientatie van je assen hebben er niets mee te maken. Post je code eens zoals het nu is?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void resize(int x1, int y1, int x2, int y2, int n)
    {       
        //Middelpunt
        float cx = (float) path.getBounds2D().getCenterX();
        float cy = (float) path.getBounds2D().getCenterY();
            
        //Zoom factor
        float xzoom = (float)(cx-x2) / (float)(cx-x1);
        float yzoom = (float)(cy-y2) / (float)(cy-y1);       
        
        //path is de Shape
        Polygon2D p = (Polygon2D)path;

        for (int i = 0; i < p.npoints; i++)
        {
            p.xpoints[i] = cx + ((p.xpoints[i]-cx)*xzoom);
            p.ypoints[i] = cx + ((p.xpoints[i]-cx)*yzoom);
        }
    }

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

En kijk nu nog eens goed naar regel 17 8)7

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
YAAYYY karma voor jou eindelijk^^

Dankjewel!
Pagina: 1