de perfecte cirkel

Status
Niet open voor verdere reacties.

Murdocki

Gebruiker
Lid geworden
7 jun 2007
Berichten
449
heya,

hebben jullie wel eens geprobeert pixel voor pixel de perfecte cirkel te tekenen? ik ben benieuwd naar jullie resultaten :).
 
Dat is toch niet zo moeilijk bijvoorbeeld in een windows forms application laat je hem een cirkel teken.

Locatie doe je 30, 30,
De dia meter doe je bijvoorbeeld 200,
Dan typ je daar achter nog eens 30

De 30 zort voor een perveckte cirkel die helemaal goed rond is.
 
ik zei pixel voor pixel ;) maar wat is dat voor functie dan waar jij het over hebt?
 
pixel voor pixel?:) kan je pixels aanspreken, zeker zijnde dat windows ze niet aanpast?

nuja herschalen zou ik doen en dan in een marge minstens 2 naast elkaar tekenen, je moet ergens de grens leggen van wanneer je nu tekent en wanneer niet. Er zal immers zo goed als geen enkele pixel percies op de juiste plaats liggen...
 
wat ik bedoel is dat je pixel voor pixel een andere kleur geeft dan de achtergrond zodat je op het einde een cirkel hebt dit kan met de win gdi. en waar ik benieuwd naar ben is jullie formules ;) ik heb hier zelf al een functie gemaakt maar daar ben ik nog niet tevreden mee dus ik zal later een plaatje posten met wat ik heb.

en je hebt idd gelijk dat er niet op iedere plek een pixel ligt. als je alles naar boven afrond komt t wel goed
 
euhm ok, ik doe een poging:)

Ik gebruik de standaard parametrisatie (r*cos(theta),r*sin(theta))

je cirkelcoords met middelpunt (x,y) zijn dan (x+r*cos(t),y+r*sin(t))

veronderstel:

methode drawpixel(p1,p2)
methode Roundabove(int) rond af naar boven

for theta = 0 .. 2*PI

drawpixel (X + Roundabove( r*cos(theta) ),Y + Roundabove( r*sin(theta) ))

loop

en je zou een cirkel moeten zien, voor R voldoende groot:)

Edit, ja wss niet natuurlijk:) herschalen nu eh, 2*pi 200 pI maken, en die transformatie ongedaan maken in sin,cos forumules zelf.
Clue zit hem erin genoeg punten te tekenen natuurlijk, en dus veel te loopen...
Zoals ik al zei in mijn eerste post, ook nog een tweede commando mss

drawpixel (X + Roundabove( r*cos(theta) ),Y + Roundabove( r*sin(theta) ) + 1)

voor twee pixels naast elkaar
 
Laatst bewerkt:
Of lekker simpel.
Met DOS Qbasic!

CLS
SCREEN 1
CIRCLE (150, 100) 150
END
:)
 
Laatst bewerkt:
een erg mooie cirkel inderdaad arre die formule kende ik nog niet waar komt die vandaan?
hier is je resultaat wat ik gemaakt heb voor je:

arre.jpg


met deze code:

Code:
    #define sin_d(x) (sin((x)*M_PI/180)) 
    #define cos_d(x) (cos((x)*M_PI/180))
    int pixx = 0;
    int pixy = 0;
    int radius = 100;
    int centerx = 400;
    int centery = 300;
    for( double x = 0.0; x < (200*2.1415); x += 0.1 )
        {
        pixx = static_cast<int>(centerx+radius*cos_d(x));
        pixy = static_cast<int>(centery+radius*sin_d(x));
        PixelDraw( static_cast<int>(pixx) ,static_cast<int>(pixy), RGB(255,255,255) );
        //PixelDraw( static_cast<int>(pixx+1) ,static_cast<int>(pixy), RGB(255,255,255) );
        }
zoals je ziet is die 2e pixel niet nodig aangezien ik x met 0.1 verhoog dus dat is redelijk intens


p.s. de mijne was was niet zo mooi ;) ik zal morgen plaatje posten

edit:
jaja ik weet het 2* static_cast, komt omdat ik de pixeldraw functie nog had staan van mijn eigen functie
LET OP PixelDraw is GEEN win gdi functie ik heb deze gemaakt voor in mijn engine
 
Laatst bewerkt:
forumule komt van cursus analyse (wiskunde) :)

gewoon wat spelen met variablen:)

je kent waarschijnlijk x^2 + y^2 = r^2

Noem je x = r*cos(t) en y = r*sin(t) blijft de gelijkheid behouden en bekom je een eenvoudige parametrisatie. Alle bollen, ellipsen etc zijn via die dingen vaak veel eenvoudiger te beschrijven dan in carthesische vorm:)

Google maar wat als je geintereseerd bent, je zal wel vanalles vinden:)
 
ok ik snap hoe je pythagoras ombouwt naar die cos en sin aangezien dit gewoon een rechthoekige driehoek is die je in die cirkel kan tekenen maar ik snap nog niet helemaal wat dat theta is. kan komen omdat ik ook nooit gesnapt heb waar pi nou eigenlijk voor staat.
twee vraagjes eigenlijk wat is dat carthesische vorm waar je het over hebt en wat je allemaal in die cursus geleerd hebt omdat ik altijd erg nieuwschierig ben naar dit soort formules. ohja kan je ook uitleggen wat theta is en waarom de loop 200*pi moet zijn
en (lol) waar naar te zoeken op google, wat is bv de naam van die persoon die deze formule gemaakt heeft?
 
:P voor alle duidelijkheid, dit is doodeenvoudig en niet waard om iemands naam aan toe te schrijven:)

carthesische coordinaten zijn (x,y,z,...) in 2D : (x,y)
Ze zijn de coordinaten die je afleest op een mooi rechthoekig assenstelsel, en de meest gebruikte. Bijvoorbeeld een rechte evenwijdig met de y as, die de x-as snijdt in 2 is bv x=2...
Echter voor vormen die niet mooi rechthoekig zijn, of recht zijn wordt alles minder mooi:)
Anyway hier zijn wat links:) ik ga geen les wiskunde geven:

http://nl.wikipedia.org/wiki/Coördinaat
http://nl.wikipedia.org/wiki/Poolcoördinaten

etc.

Waarom je nu die 200 Pi pakt en nog een mooie cirkel krijgt is een beetje geluk:)
Sin en Cos zijn periodieke functies. In princiepe zou 0 tot 2*Pi voldoende zijn voor een volledige cirkel, maar omwille dat je waarschijnlijk met integeres werkt zal hij mss maar 3 getallen afgaan. Als je tot 600 (ongeveer 200 Pi) laat gaan, zal hij veel meer punten afgaan, en door juist die periodiciteit zal hij veel meer punten gaan tekenen...

Je kan het altijd zelf eens proberen met pen en potlood en een rekenmachine.
Teken een carthesisch assenstelsel, en teken cooridnaten (cos(1),sin(1)), (cos(2),sin(2)), ...
Je zal zien dat naarmate je erg veel punten tekent je de hele cirkel zal krijgen...
Een grafisch rekenmachine kan ook wonderen doen:)

Oh en die theta is wat je de parameter noemt... De veranderlijke... Tja:P zie cursus wiskunde:)
 
gisteren nadat ik naar bed ging kwam ik er ineens achter wat die theta nou eigenlijk was. deze is hetzelfde als die 200*3.14. het is namenlijk de hoek dus 200*3.14/360=1.75 dit betekent dus dat je 1,75 cirkel tekent. je zou hier voor het gemak gewoon 360 neer moeten zetten zodat je weet dat het met graden te maken heeft. de intensiteit van de cirkel kan je dan aanpassen met de stapgrootte. het leuke van deze formule is dat je dus zelf aan kunt passen om de hoeveel graden je een punt wilt teken, wat erg handig is als je een camera ergens omheen wilt laten draaien en je wilt de rotatiesnelheid in graden aangeven.

p.s. 2*3.14 is niet genoeg aangezien het antwoord hiervan 6 is en een cirkel 360 graden is.

hier nog een leuk plaatje gemaakt met gebruik van deze geweldige formule, kijk naar de rode stip en val misselijk neer :P

hypno.gif


je kunt ook gelijk de zwakheden van carthetische cirkels zien
 
ik had beloofd nog een plaatje te posten van de cirkel die ik had gemaakt. aangezien ik m'n oude functie per ongeluk heb overschreven kan ik dat plaatje niet meer posten. wel kan ik nog een stukje code posten voor hoe ik aan de coordinaten kwam. niet echt effectief maar hey het werkte.

p.s. dit is de code die ik later in m'n vieuw matrix geplaatst heb dus je zult geen tekeningen of iets ermee krijgen maar je krijgt iig een idee hoe ik het gedaan heb

Code:
loglist RotateCameraSteerLeft_Orbit( float& cameraposx, float& cameraposz,
                                   float& cameralookx, float& cameralookz,
                                   float cameraradius )
    {
    //declaring vars which are used to calculate where the camerapos and cameralookpos should go
    int circlequadrant;//1:topleft, 2:topright, 3:bottomleft, 4:bottomright
    float centerx = cameralookx;//( cameraposx + cameralookx ) / 2;
    float centerz = cameralookz;//( cameraposz + cameralookz ) / 2;
    float radius = cameraradius;
    loglist returnlist;
    sprintf( returnlist.extras, "%s", "started rotcamstrlft_orbit function-");


    //filling in the circlequadrant variable. this var is used to determine which ca***ation
    //is being used to calculate where the camerapos and cameralookpos should move.
    if( cameraposx < cameralookx )//the camera is in the left quadrant(looking along the z axis)
        {
        if( cameraposz > cameralookz )//the camera is in the top quadrant(looking along the y axis)
            {
            circlequadrant = 1;
            }
        else if( cameraposz < cameralookz )//the camera is in the bottom quadrant(looking along the y axis)
            {
            circlequadrant = 3;
            }
        else//the camera is in line with the look(looking along the z axis)
            {
            cameraposz-=rotatespeed;
            //cameralookz-=rotatespeed;
loglist temp(  circlequadrant, centerx, centerz, rotatespeed,
               cameralookz, cameralookx, cameraposx, cameraposz );
            returnlist = temp;
            return returnlist;
            }
        }
    else if( cameraposx > cameralookx )//te camera is in the right quadrant(looking along the z axis)
        {
        if( cameraposz > cameralookz )//the camera is in the top quadrant(looking along the y axis)
            {
            circlequadrant = 2;
            }
        else if( cameraposz < cameralookz )//the camera is in the bottom quadrant(looking along the y axis)
            {
            circlequadrant = 4;
            }
        else//the camera is in line with the look(looking along the z axis)
            {
            cameraposz+=rotatespeed;
            //cameralookz+=rotatespeed;
loglist temp(  circlequadrant, centerx, centerz, rotatespeed,
               cameralookz, cameralookx, cameraposx, cameraposz );
            returnlist = temp;
            return returnlist;
            }
        }
    else//the camera is in line with the look(looking along the z axis)
        {
        if( cameraposz < cameralookz )
            {
            cameraposx+=rotatespeed;
            }
        else if( cameraposz > cameralookz )
            {
            cameraposx -= rotatespeed;
            }
        else
            {
            //this should never be the case
            }
        //cameralookx+=rotatespeed;
loglist temp(  circlequadrant, centerx, centerz, rotatespeed,
               cameralookz, cameralookx, cameraposx, cameraposz );
            returnlist = temp;
            return returnlist;
        }
for( int x = 0; x < 1000; x++ )
{
    if( circlequadrant == 1 )//the camera is in the topleft quadrant(looking along the y axis)
        {
        if( sqrt((cameraposz-cameralookz)*(cameraposz-cameralookz)+(cameralookx-cameraposx)*(cameralookx-cameraposx)) <= radius )
            cameraposz-=rotatespeed;
        if( sqrt((cameraposz-cameralookz)*(cameraposz-cameralookz)+(cameralookx-cameraposx)*(cameralookx-cameraposx)) > radius )
            cameraposx-=rotatespeed;
        }
    if( circlequadrant == 2 )//the camera is in the topright quadrant(looking along the y axis)
        {
        if( sqrt((cameraposz-cameralookz)*(cameraposz-cameralookz)+(cameraposx-cameralookx)*(cameraposx-cameralookx)) <= radius )
            cameraposx-=rotatespeed;
        if( sqrt((cameraposz-cameralookz)*(cameraposz-cameralookz)+(cameraposx-cameralookx)*(cameraposx-cameralookx)) > radius )
            cameraposz+=rotatespeed;
        }
    if( circlequadrant == 3 )//the camera is in the bottomleft quadrant(looking along the y axis)
        {
        if( sqrt((cameralookz-cameraposz)*(cameralookz-cameraposz)+(cameralookx-cameraposx)*(cameralookx-cameraposx)) <= radius )
            cameraposz-=rotatespeed;
        if( sqrt((cameralookz-cameraposz)*(cameralookz-cameraposz)+(cameralookx-cameraposx)*(cameralookx-cameraposx)) > radius )
            cameraposx+=rotatespeed;
        }
    if( circlequadrant == 4 )//the camera is in de bottomright quadrant(looking along the y axis)
        {
        if( sqrt((cameralookz-cameraposz)*(cameralookz-cameraposz)+(cameraposx-cameralookx)*(cameraposx-cameralookx)) <= radius )
            cameraposz+=rotatespeed;
        if( sqrt((cameralookz-cameraposz)*(cameralookz-cameraposz)+(cameraposx-cameralookx)*(cameraposx-cameralookx)) > radius )
            cameraposx+=rotatespeed;
        }
}
    loglist temp( circlequadrant, centerx, centerz, rotatespeed,
                  cameralookz, cameralookx, cameraposx, cameraposz );
    returnlist = temp;
    return returnlist;
    }

ik doe dus eerst opzoeken in welk quadrant het punt zit zodat ik weet welke kant hij op moet daarna beweeg ik hem en is de straal te groot dan beweeg ik hem weer naar binnen
als je je afvraagt waarom ik die for in x 0 1000 daar gezet heb dat is omdat ik wat preciezer op de cirkel wilde zitten dus ik heb m'n bewegingssnelheid 1000 keer kleiner gemaakt maar wel 1000 keer bewegen. dan heb je dus dat je minder als driehoekjes over de cirkellijn heen beweegt. mja nu heb ik die mooie formule dus ik zal dit niet meer nodig hebben. ik ga het nu gewoon aangeven in een aantal graden per rotatie_tick
 
Deze topic herinnerd me weer aan vroeger, als ik niets te doen had tijdens de wiskunde les ging ik stippen in een cirkel tekenen en die met elkaar verbinden. Bracht me op het idee dat in code te maken:

http://www.svdww.com/cirkel.exe

Gebruik + en - om het aantal punten te bepalen.
 
p.s. 2*3.14 is niet genoeg aangezien het antwoord hiervan 6 is en een cirkel 360 graden is.

Toch wel... Als je radialen gebruikt.
sin(x) is gedefinieerd als periodiek op 2*Pi in standaard radialen, wat vaak handiger werkt dan graden...

Mooie cirkeltjes btw:)
 
@arre
aha vandaar dat die functie niet zo goed werkte en ik het volgende neer moest zetten om ze om te vormen maar graden

#define sin_d(x) (sin((x)*M_PI/180))
#define cos_d(x) (cos((x)*M_PI/180))

ik vind radialen niet handig snap ook niet waar ze voor zijn eigenlijk. geef gwn alles aan in graden :P

@svdww coole app hoor. ik ga hem proberen na te maken :D
 
Radialen is gewoon echte wiskunde, graden zijn voor 'mietjes' ;-)

(Geintje moet kunnen toch...)
Probleem met cirkels op beeldschermen was vroeger dat de afstand horizontaal niet echt gelijk was aan die verticaal. Kun je keurig cirkels in pixels uitrekenen maar d'r komt mooi een ovaal op het scherm.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan