Page 1 of 2 1 2 LastLast
Results 1 to 15 of 20

Thread: Strakke lijnen en cirkels tekenen

  1. #1

    Strakke lijnen en cirkels tekenen

    Hallo allemaal.

    Via onderstaande code ben ik een voetbalveld aan het tekenen, helaas valt het resultaat tot nu toe tegen.

    Hier de code:

    Code:
    procedure TForm1.FormPaint(Sender: TObject);
    
    begin
      with Canvas do
      begin
        Pen.Style   := psSolid;
        Pen.Color   := clwhite;
        Pen.Width   := 3;
        Brush.Style := bsclear;
    
        Rectangle(210,40,1680,970);// Is buitenzijde veld
        Rectangle(210,222,441,788);// Is strafschopgebied links
        Rectangle(210,377,287,633);// Is doelgebied links
        Rectangle(180,454,210,556);// Is doel links
        Ellipse(815,375,1075,635); // Is middencirkel
        MoveTo(945,40); LineTo(945,969); // Is middenlijn
        Rectangle(1449,222,1680,788);// Is strafschopgebied rechts
        Rectangle(1603,377,1680,633);// Is doelgebied rechts
        Rectangle(1680,454,1710,556);// Is doel rechts
        Pen.Width   := 4;
        Ellipse(942,501,949,507); // Is middenstip
        Ellipse(361,502,367,508); // Is strafschopstip links
        Ellipse(1523,502,1529,508); // Is strafschopstip rechts
        MoveTo(40,40); LineTo(945,969); // Is extra schuine lijn (alleen voor voorbeeld)
      end;
    
    end;
    Ik krijg alleen geen strakkel lijnen en cirkels. Alleen de rechte lijnen zijn mooi strak.
    De middencirkel lijkt uit kleinde blokjes te bestaan en de schuine lijn (deze hoort er niet in maar is ter verduidelijking toegevoegd) ook.
    Ook de stippen zijn niet strak maar lijken op miniatuur bloemkolen.

    Is er een oplossing om deze lijnen strak te krijgen?
    Geniet maar drink met je maten.

    Geen liters maar vaten!!!

  2. #2
    Om diagonale en ronde lijnen er strakker uit te laten zien, kun je gebruik maken van anti-aliasing. Pixels die door de lijn verdeeld zouden worden, krijgen een kleur tussen groen en wit in. Hoe meer van de pixel wit zou moeten zijn, hoe witter de pixel wordt, en andersom.

    Blijkbaar heeft een TCanvas in FreePascal een property AntiAliasingMode, die je op amOn kan zetten. Ik heb zelf geen FreePascal, dus ik kan verder niet testen hoe dat werkt.
    1+1=b

  3. #3
    Hoi Kluns,

    Zoals GolezTrol al aangeeft. Alle getekende lijnen die niet exact horizontaal of verticaal op je scherm staan zien er over het algemeen blokkerig uit (afhankelijk van de resolutie en het zicht van de aanschouwer).

    En inderdaad wordt hiervoor (of eigenlijk tegen) anti-aliasing gebruikt.

    Nu hoef je dat anti-aliasing gelukkig niet helemaal zelf uit te vogelen ;-).

    Kijk bijvoorbeeld eens naar de AGGPAS library (http://www.crossgl.com/aggpas/).

    groetjes,


    Domderdedomdiedom. Ik zie het nu pas ops: Probeer eens een andere penwidth die iets minder groot is. Je gebruikt nu nl pen.width=3 en pen.width=4. Als ik in 1920x1080 zit zie ik er (bijna) niets van, maar ik kan mij zo voorstellen dat bv een resolutie van 320x200 erg blokkerig overkomt. Vooral met cirkels is dit lastig.
    Ik snap dat je een dikkere lijn-breedte wil hebben, maar dat kost je in dit geval dus het nauwkeuriger tekenen (nl een pen.width van 1 is het meest nauwkeurig). Wil je een dikkere lijn hebben plaats dan een paar crikels naast elkaar met een andere radius. of teken twee cirkels. Eerst de buitenste dan de binnenste en kleur het tussenvlak in.
    Last edited by flabber; 04-Aug-12 at 17:17.

  4. #4
    Ik zie geen verschil met amOn en amOff (lazarus 1.1/Fpc 2.6.0/Win7).
    Ik vind het overigens in beide gevallen wel meevallen.

    Bart

  5. #5
    Bart,

    Ik gebruik overigens Lazarus 9.30.4 en op mijn laptop heb ik windows 7.
    Ik weet niet of dit er ook nog invloed op heeft?

    Jij gebruikteen andere versie , hoe zet jij amOn en amOff want in mijn Lazarus versie kan ik dat niet vinden.

    Als ik overschakel op de 64 bits versie is het dan toch mogelijk om de programma's die ik maak op een 32 bits computer te gebruiken?

    Flabber,

    Het tekenen met een dunnere lijn geeft weinig verbetering.
    Ik heb ook de AGGPAS library even doorgenomen maar hier kom ik tot nu toe niet erg uit.
    Moet je de gedownloade bestanden ergens installeren?
    Geniet maar drink met je maten.

    Geen liters maar vaten!!!

  6. #6
    Als ik overschakel op de 64 bits versie is het dan toch mogelijk om de programma's die ik maak op een 32 bits computer te gebruiken?
    Een 64-bit programma kan niet draaien op een 32 bit OS. Andersom wel.
    1+1=b

  7. #7
    GolezTrol,

    Het is mij bekend dat een 64 bit programma niet op een 32 bit computer kan draaien en andersom wel.

    Uit jou opmerking maak ik op dat een 64 bit Lazarus alleen 64 bit programma's kan maken of heb ik dit mis?
    Geniet maar drink met je maten.

    Geen liters maar vaten!!!

  8. #8
    Dan begreep ik je vraag verkeerd.
    Ik ben zelf geen Lazarus-gebruiker, maar ik meen dat het wel mogelijk moet zijn om 32-bit executables te compileren met de 64-bit-versie, zolang je maar de juiste compiler hebt.

    Even snel gezocht, en onder andere deze pagina gevonden die duidelijkheid zou moeten scheppen, maar ik vond ook diverse fora waarop gesuggereerd werd dat het eenvoudiger is om de 32-bit en 64-bit versies naast elkaar te installeren, en per situatie dus de juiste IDE te gebruiken.
    Ik kan er zelf niets aan toevoegen.
    1+1=b

  9. #9
    Quote Originally Posted by Kluns View Post
    Het tekenen met een dunnere lijn geeft weinig verbetering.
    hmz, das raar. Met het risico dat ik een huh terugkrijg, weet je zeker dat je canvas niet opgeschaalt wordt ? of zit je misschien echt in een erg lage resolutie ? (toevallig met een verrekijker naar het scherm aan het turen )

    Quote Originally Posted by Kluns View Post
    Moet je de gedownloade bestanden ergens installeren?
    Oei, dat erg basic informatie over hoe je libraries van derden installeert. Kijk anders eens hier voor meer informatie over het installeren van zogenaamde packages. De informatie kan altijd later nog eens van pas komen (zie beneden).

    Maar gelukkig en door mij overkeken , aggpas is al standaard aanwezig in lazarus

    Quote Originally Posted by Kluns View Post
    Ik heb ook de AGGPAS library even doorgenomen maar hier kom ik tot nu toe niet erg uit.
    Probeer eens te kijken naar een demo van aggpas op een lcl-canvas. Als je lazarus standaard geinstallerd hebt dan bevinden de aggpas demos zich (bij mij tenminste) in <waar je lazarus hebt geinstallerd>/components/aggpas/lazarus/example/*. Daar staan drie demos die je in kunt laden (hoofdmenu->project->open project) en compileren om uit te proberen.

    Quote Originally Posted by GolezTrol;
    ...dat het eenvoudiger is om de 32-bit en 64-bit versies naast elkaar te installeren, en per situatie dus de juiste IDE te gebruiken.
    Zoals altijd in dit soort situaties, het antwoord is ja en nee.

    Voor Kluns: kijk eens naar project opties, selecteer Code generation in de tree-list en kijk op het tabblad rechts. Daar vindt je een hoofdstukje genaamd Target OS/Target CPU. In de uitklapmenu's kun je dan je gewenste 'target' selecteren.

    Maar zoals je wellicht zult raden, voor elke target cpu is een zogenaamde cross-compiler nodig en voor zover ik weet worden deze niet allen standaard met lazarus meegeleverd en zul je deze zelf handmatig moeten (compileren en) installeren. Ik moest dit in ieder geval doen voor het NDS platform.

    Ik ben daar helaas ook niet erg goed in dus misschien (en als je het nog nodig mocht hebben) dat iemand anders daar wat meer informatie over kan verschaffen. De cross-compile wiki pagina's zijn inderdaad niet erg duidelijk voor een leek (zoals ik dus).

    In dat opzicht is het advies wat GolezTrol had gevonden om beiden 32 en 64 bit versies naast elkaar te installeren misschien zo slecht nog niet.

    Ik hoop in ieder geval dat je nu verder kunt knutselen met aggpas. Zo zie je maar weer dat een simpel voetbalveld niet zo simpel is dan het lijkt

    groetjes,


    he bah, mijn geheugen is als een zeef.

    Quote Originally Posted by Kluns View Post
    Jij gebruikteen andere versie , hoe zet jij amOn en amOff want in mijn Lazarus versie kan ik dat niet vinden.
    Het helpt misschien om eens in de help te kijken Kluns . Een Lazarus-Canvas heeft een property genaamd Antialiasingmode.

    Deze property kan een van de volgende drie waarden hebben
    1 amDontCare
    2 amOn
    3 amOff

    Ergo:
    Jouwcanvas.Antialiasingmode := amOn;
    en
    Jouwcanvas.Antialiasingmode := amOff;
    of
    Jouwcanvas.Antialiasingmode := amDontCare;

    Hopelijk helpt dit je ook weer een stukje verder.
    Last edited by flabber; 05-Aug-12 at 04:53.

  10. #10
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Een 32-bit Lazarus kan wel 64-bit code genereren. Zie b.v. Code Typhon, en ook FPC heeft een 32-bit->64-bit cross setje.

    Er zitten dan twee compilers in. Een 64-bit lazarus kan zo ook 32-bit code generen.

    Het enige wat mogelijk niet kan is de compiler _zelf_ crosscompilen van 64-bit naar 32-bit. Dit omdat de 32-bit codegenerator zwaar "extended" gebruikt, en extended is een x87 only type.

    Hoewel 64-bit x86_64 wel de x87 FPU hardware ondersteunt, was deze in ABI documentatie doorgaans verboden. Ik weet niet of daar inmiddels een uitzondering voor is gemaakt in FPC.

    Er is een algemeen soft floating point framework, maar 80-bits is daar nog niet af.

    Ik ben zelf echter ook meer voor het naast elkaar installeren. Alles wat daar voor nodig is is geloof ik een extra parameter aan Lazarus zodat die de configuratie in een andere map stouwt. (-pcp=)
    In feite heeft Lazarus de mogelijkheid voor een volledig "portableapp" installatie, alleen de installer ondersteunt het niet. Dit is ook makkelijk om even een oude versie te restoren en te testen.

    Of een kopietje te hebben met andere versies componenten. (b.v. eentje met de laatste gevalideerde ZEOS, en eentje om met trunk te experimenteren). Of een versie delen met een dual boot windows (Windows 8 komt eraan!) etc etc.

    Toen ik een tijdje serieus aan een lazarus project werkte, maakte ik iedere 3 maanden de lazarus installatie een backup, componenten en al. Die installaties waren zo getweaked (1 minuut werk) dat je ze op een willekeurige plek kon restoren, project openen, compileren, klaar. In 1.0 (nu RC, release geplanned in september, zal wel oktober worden) zijn de mogelijkheden qua relatieve paden e.d. weer uitgebreid.

    Omdat onder Lazarus geen paden naar componenten in applicatie projecten zitten (*), is restoren zo simpel als uitpakken en dan kan je al het project laden.

    (*) In Lazarus leg je een dependency op een component, en de paden tijdens installatie van die component worden dan automatisch toegevoegd.
    Last edited by marcov; 05-Aug-12 at 14:01.

  11. #11
    Weer wat geprutst maar erg veel verder kom ik niet.

    Ik werk met een schermresolutue van 1.920x1.080, dus dat kan de oorzaak niet zijn.

    Jouwcanvas.Antialiasingmode := amOn; helpt ook niet.

    Als ik van de pagina: (http://www.crossgl.com/aggpas/) de demo uit probeer krijg ik de volgende melding:
    unit1.pas(8,3) Fatal: Can't find unit Agg2D used by Unit1

    Ik heb dan de volgende code in de unit staan:

    Code:
    unit Unit1; 
    
    
    interface
    
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs ,
      Agg2D, ExtCtrls ;
    
    type
      TForm1 = class(TForm)
        Image1: TImage;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormResize(Sender: TObject);
      private
        { Private declarations }
        VG : TAgg2D;
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.DFM}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     ControlStyle:=ControlStyle + [csOpaque ];
    
     VG:=TAgg2D.Create;
    
     Image1.Picture.Bitmap.PixelFormat:=pf32bit;
    
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
     VG.Destroy;
    
    end;
    
    procedure TForm1.FormResize(Sender: TObject);
    begin
     Image1.Picture.Bitmap.Width :=ClientWidth;
     Image1.Picture.Bitmap.Height:=ClientHeight;
    
     if VG.Attach(Image1.Picture.Bitmap ) then
      begin
       VG.ClearAll(255 ,255 ,255 );
       VG.LineWidth(10 );
       VG.LineColor($32 ,$cd ,$32 );
       VG.FillColor($ff ,$d7 ,$00 );
    
       VG.Star(100 ,100 ,30 ,70 ,55 ,5 );
    
      end;
    
    end;
    
    end.
    Geniet maar drink met je maten.

    Geen liters maar vaten!!!

  12. #12
    Hoi kluns,

    Om gebruik te kunnen maken van units van derden, dienen deze eerst op de juiste wijze geinstalleerd te worden voor lazarus.

    De foutmelding 'can't find unit blah' wijst erop dat de door jouw aangesproken unit niet gevonden kan worden door lazarus. (terzijde: heerlijk als een programma je precies verteld hoe het ervoor staat)

    De uitbreidings-units (van derden) die je wilt gebruiken dienen in de daarvoor bestemde locaties in je lazarus installatie geinstalleerd te worden. Hoe je dit precies doet is afhankelijk van het type units dat door deze uitbreding wordt meegeleverd. Meestal vermeld deze derde hoe e.e.a dient te worden geinstalleerd en kan dit dus per uitbreiding verschillen. Vandaar ook enigzins mijn verwijzing naar de internetpagina.

    Maar, zoals ik al had aangegeven heb ik een foutje gemaakt. Excuses daarvoor.

    >>> AGGPAS is standaard al aanwezig in een normale Lazarus-installatie. <<<

    Daarom verwees ik ook naar de AGGPAS demo, omdat deze demo uitstekend laat zien hoe je een AGGPAS-canvas dient te gebruiken in combinatie met lazarus.

    Ik zou je dus (opnieuw) willen adviseren deze demo in te laden en te bekijken, zodat het gebruik ervan in lazarus je duidelijk wordt.

    Je code is al een eind in de goede richting, echter zijn er enkele kleine veranderingen als je de AGGPASS-canvas met de lazarus-lcl wilt gebuiken.

    Mocht je er nog steeds niet uitkomen dan hatseflats ik wel wat in elkaar.

    Ik plaats enkel wel mijn twijfels omdat je zelfs op zo'n hoge resolutie vermeldt dat je midden-stip er als een bloemkool uitziet, dit komt mij erg raar over en is niet door mij te herproduceren. Maar misschien verschillen we gewoon van interpretatie

    groetjes,

  13. #13
    Nah, om de boel maar een beetje kracht bij te zetten (en omdat ik toch geen oog dichtdoe).

    Ik de boel nog eens getekend op de canvas van de form. Hoe hard ik ook kijk, ik kan er geen bloemkool van maken

    Dus voor de zekerheid maar een snapshot van de form toegevoegd zoals het er bij mij uitziet (gaarne op originele formaat bekijken, anders zou daar misschien verwarring over kunnen ontstaan).

    De gegevens die ik gebruikt heb komen van dit wiki artikel vandaan, daar stond een mooi plaatje met alle afmetingen (ik heb de ballen verstand van voetbal nl).

    En dit is de magische brij aan spagetthi:

    Code:
    unit Unit1; 
    
    (*
      5 augustus 2012
    
      Het tekenen van een voetbalveld op een form-canvas.
    
      Dit naar aanleiding van een vraag waarom de cirkels er zo blokkerig uitzien.
    
      Deze unit is gebaseerd op een standaard TForm.
      Geen enkele property is visueel aangepast en hebben dus hun default
      waarden. Enige uitzondering hierop zijn standaard events, mar deze zijn
      zichtbaar aanwezig in deze unit.
      Properties die wel dienen te worden aangepast worden programmatisch aangepast
      zodat zichtbaar is wat er nu precies met de properties can de verschillende
      componenten gebeurt.
    
      Het voetbalveld is niet geheel compleet. De volgende zaken ontbreken:
      - de corner-hoek-geval-cirkels
      - Alles wat verder vergeten is
    *)
    
    
    {$mode objfpc}{$H+}
    
    
    interface
    
    uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs; 
    
    type
    
      { TForm1 }
    
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormPaint(Sender: TObject);
        procedure FormResize(Sender: TObject);
      private
        { private declarations }
      public
        { public declarations }
      end; 
    
    var
      Form1: TForm1; 
    
    
    implementation
    
    {$R *.lfm}
    
    
    
    type
      // Een definitie voor een Arc object, zie Lazarus Help -> TCanvas.arc();
      TArc = record
        Left, Top, Bottom, Right: integer;
        sx, sy: integer;
        ex, ey: integer;
      end;
    
      // De benodigdheden voor 1 helft van een voetbalveld
      TVoetbalVeldHelft = record
        StrafschopGebied  : TRect;         // coordinaten van het Strafschopgebied
        DoelGebied        : TRect;         // coordinaten van het doelgebied
        DoelCirkel        : TArc;          // coordinaten van de doelcirkel
        StrafschopStip    : TRect;         // coordinaten van de strafschopstip
      end;
    
      // De benodigdheden voor 1 compleet voetbalveld
      TVoetbalVeld = record
        Veld         : TRect;              // coordinaten van het voetbalveld
        LH           : TVoetbalVeldHelft;  // coordinaten van de linker speelhelft
        RH           : TVoetbalveldHelft;  // coordinaten van de rechter speelhelft
        Middenlijn   : TRect;              // coordinaten van de middellijn
        MiddenCirkel : TRect;              // coordinaten van de middencirkel
        MiddenStip   : TRect;              // coordinaten van de middenstip
      end;
    
    
    const
      {
        De afmetingen van een voetbalveld geplaatst in constanten.
        Afmetingen zijn gebaseerd op het wikipedia artikel genaamd Voetbalveld
        waarbij een SVG plaatje staat met alle afmetingen.
        De hier gekozen waarden is een willekeurige (niet op voetbalbondregels)
        selectie van afmetingen welke het beste uitkwamen.
        De afmetingen zijn gegeven in meters en worden door de routines geschaald
        als het voetbalveld daadwerkelijk op het scherm getekend wordt.
      }
    
      Veld_Lengte              = 100.00;     // Lengte van een voetbalveld
      Veld_Breedte             = 50.00;      // Breedte van een voetbalveld
      Middencirkel             = 9.15;       // Radius van de middencirkel
      StrafSchopGebied_Breedte = 40.30;      // Breedte van het strafschopgebied
      StrafSchopGebied_Lengte  = 16.50;      // Lengte van het strafschopgebied
      DoelGebied_Breedte       = StrafSchopGebied_Breedte - 11.00 * 2;
      DoelGebied_Lengte        = 5.50;
      DoelCirkel               = 9.15;       // radius van de doelcirkel
      StrafSchopAfstand        = 11.00;      // Afstand van de strafschopstip
    
      VirtualBorderSize        = 100;
    
    var
      // Men definiere een voetbalveld
      EenVoetBalVeld: TVoetbalVeld;
    
      {
        Om het voetbalveld te tekenen wordt de volgende strategie toegepast:
        - Het TForm mag niet kleiner worden dan een vooraf bepaalde hoogte
          en breedte. Dit om rariteiten te voorkomen tijdens het tekenen.
        - Voor het tekenen van het voetbalveld wordt er gebruik gemaakt van een
          kleine virtuele border rondom het voetbalveld, zodat het getekende beter
          overkomt.
        - Op het moment dat het TForm vergroot wordt, wordt bepaald welke afmeting
          van het TForm (lengte of breedte) bepalend is voor het geschaald kunnen
          tekenen van het voetbalveld. Immers (als alles in verhouding moet worden
          getekend) zal de (binnenste) breedte van het TForm 2x zo groot moeten
          zijn als de (binnenste) hoogte van datzelfde formulier (en vice versa).
        - Als bekend is welke afmeting van het TForm bepalend is dan wordt hierop
          de schalingsfactor bepaald.
        - Alle afmetingen/coordinaten kunnen daarna worden berekend op basis van de
          (voorgedefineerde) constante afmetingen van een voetbalveld en de
          schalingsfactor.
        - Als basis voor het berekenen van de coordinaten wordt uitgegaan van een
          enkel punt (genaamd middenMidden/MM) en dit punt zal dan ook in het
          midden van het TForm gepositioneerd zijn.
        - Als alle benodigde coordinaten zijn berekend kunnen we het veld
          daadwerkelijk gaan tekenen.
      }
    
    
    
    
    
    {
      De functie voor het bepalen van de schalingsfactor.
    }
    function BepaalSchaalFactor(TekenGebiedBreedte, TekenGebiedHoogte: integer): single;
    begin
      (*
    
      - Omdat we de minimale constraints van het tekengebied hebben gezet
        zal deze nooit kleiner zijn dan Breedte x Hoogte (= 100x50, zie formcreate).
        De hier gekregen lengte en breedte waarden worden dus bepaald door de
        aanroeper middels het vergroten/verkleinen van het TForm.
      - De uiteindelijke (opgeschaalde) waarde van de lengte (in pixels) van het
        voetbalveld wordt bepaald door de ClientWidth property van het TForm
      - De uiteindelijke (opgeschaalde) waarde van de Breedte (in pixels) van het
        voetbalveld wordt bepaald door de ClientHeight property van het TForm
      - De schaalfactor is afhankelijk van ofwel de lengte danwel de breedte die
        aam deze routine is meegegeven.
        Het voetbalveld moet immers wel (in verhouding) op het TForm kunnen passen,
        zodat het nodig is te bepalen welke afmeting verantwoordelijk kan worden
        gehouden voor het zo groots mogelijk kunnen tekenen van het voetbalveld
        (met inachtnemning van de opschaling).
      - Om uit te maken of de lengte of de breedte verantwoordelijk is voor de
        schalingsfactor passen we een eenvoudige strategie toe (in pseudocode):
    
          Als Lengte < (Breedte * 2) dan schaalfactor afhankelijk van lengte
    
          Of ook wel:
    
          Als Breedte < (Lengte / 2) dan schaalfactor afhankelijk van breedte
    
        Het aan den lezer zelf te achterhalen uit welke toverhoed deze magische
        factor 2 ineens vandaan is getoverd ;-)
    
      DUS:
      *)
    
      if TekenGebiedBreedte < (TekenGebiedHoogte * 2) then
      begin
        // Schaalfactor wordt bepaald door de Lengte
        Result := TekenGebiedBreedte / Veld_Lengte;
      end
      else
      begin
        // Schaalfactor wordt bepaald door de breedte
        Result := TekenGebiedHoogte / Veld_Breedte;
      end;
    end;
    
    
    {
      Het herschalen van alle coordinaten op basis van de nieuwe (meegegeven) dimensies
    }
    procedure HerSchaalVeldCoordinaten(var Veld: TVoetbalVeld; TekenGebiedBreedte, TekenGebiedHoogte: integer);
    var
      MM              : TPoint;   // Het MiddenMidden van het tekengebied
      Schalingsfactor : Single;   // Een factor om mee te kunnen schalen
    begin
      // Eerst dient de schalingsfactor bepaald te worden
      // Opm: Er wordt een border van de dimensies afgetrokken
      SchalingsFactor := BepaalSchaalFactor(TekenGebiedBreedte - VirtualBorderSize,
                                            TekenGebiedHoogte  - VirtualBorderSize);
    
      // bepaal het MiddenMidden van het tekengebied
      MM.x := TekenGebiedBreedte div 2;
      MM.y := TekenGebiedHoogte  div 2;
    
      // Opm: Berekenen de belangrijkste coordinaten vanuit het middenpunt MM
    
      {- het veld Zelf -}
      Veld.Veld.Top    := MM.y - round(Veld_Breedte / 2 * SchalingsFactor);
      Veld.Veld.Left   := MM.x - round(Veld_Lengte  / 2 * SchalingsFactor);
      Veld.Veld.Bottom := MM.y + round(Veld_Breedte / 2 * SchalingsFactor);
      Veld.Veld.Right  := MM.x + round(Veld_Lengte  / 2 * SchalingsFactor);
    
      {- de middenlijn -}
      Veld.Middenlijn.Top    := Veld.veld.Top;
      Veld.Middenlijn.Left   := MM.x;
      Veld.Middenlijn.Bottom := Veld.Veld.Bottom;
      Veld.Middenlijn.Right  := MM.x;
    
      {- de middencirkel -}
      Veld.MiddenCirkel.Top    := MM.y - Round(MiddenCirkel * SchalingsFactor);
      Veld.MiddenCirkel.Left   := MM.x - Round(MiddenCirkel * SchalingsFactor);
      Veld.MiddenCirkel.Bottom := MM.y + Round(MiddenCirkel * SchalingsFactor);
      Veld.MiddenCirkel.Right  := MM.x + Round(MiddenCirkel * SchalingsFactor);
    
      {- de middenstip -}
      Veld.MiddenStip.Top    := MM.y - 3;
      Veld.MiddenStip.Left   := MM.x - 3;
      Veld.MiddenStip.Bottom := MM.y + 3;
      Veld.MiddenStip.Right  := MM.x + 3;
    
    
      {- de strafschopgebieden -}
      Veld.LH.StrafschopGebied.Top    := MM.y - round(StrafschopGebied_Breedte / 2 * SchalingsFactor);
      Veld.LH.StrafschopGebied.Left   := Veld.Veld.Left;
      Veld.LH.StrafschopGebied.Bottom := MM.y + round(StrafschopGebied_Breedte / 2 * SchalingsFactor);
      Veld.LH.StrafschopGebied.Right  := Veld.Veld.Left + round(StrafschopGebied_Lengte * SchalingsFactor);
    
      Veld.RH.StrafschopGebied.Top    := MM.y - round(StrafschopGebied_Breedte / 2 * SchalingsFactor);
      Veld.RH.StrafschopGebied.Left   := Veld.Veld.Right - round(StrafschopGebied_Lengte * SchalingsFactor);
      Veld.RH.StrafschopGebied.Bottom := MM.y + round(StrafschopGebied_Breedte / 2 * SchalingsFactor);
      Veld.RH.StrafschopGebied.Right  := Veld.Veld.Right;
    
    
      {- de strafschopstippen -}
      Veld.LH.StrafschopStip.Top    := MM.y - 3;
      Veld.LH.StrafschopStip.Left   := Veld.Veld.Left + Round(StrafSchopAfstand * SchalingsFactor) - 3;
      Veld.LH.StrafschopStip.Bottom := MM.y + 3;
      Veld.LH.StrafschopStip.Right  := Veld.Veld.Left + Round(StrafSchopAfstand * SchalingsFactor) + 3;
    
      Veld.RH.StrafschopStip.Top    := MM.y - 3;
      Veld.RH.StrafschopStip.Left   := Veld.Veld.Right - Round(StrafSchopAfstand * SchalingsFactor) - 3;
      Veld.RH.StrafschopStip.Bottom := MM.y + 3;
      Veld.RH.StrafschopStip.Right  := Veld.Veld.Right - Round(StrafSchopAfstand * SchalingsFactor) + 3;
    
    
      {- de doelgebieden -}
      Veld.LH.DoelGebied.Top    := MM.y - round(DoelGebied_Breedte / 2 * SchalingsFactor);
      Veld.LH.DoelGebied.Left   := Veld.Veld.Left;
      Veld.LH.DoelGebied.Bottom := MM.y + round(DoelGebied_Breedte / 2 * SchalingsFactor);
      Veld.LH.DoelGebied.Right  := Veld.Veld.Left + round(DoelGebied_Lengte * SchalingsFactor);
    
      Veld.RH.DoelGebied.Top    := MM.y - round(DoelGebied_Breedte / 2 * SchalingsFactor);
      Veld.RH.DoelGebied.Left   := Veld.Veld.Right - round(DoelGebied_Lengte * SchalingsFactor);
      Veld.RH.DoelGebied.Bottom := MM.y + round(DoelGebied_Breedte / 2 * SchalingsFactor);
      Veld.RH.DoelGebied.Right  := Veld.Veld.Right;
    
    
      {- de doelcirkels -}
      Veld.LH.DoelCirkel.Top    := MM.y - Round(DoelCirkel * SchalingsFactor);
      Veld.LH.DoelCirkel.Left   := Veld.Veld.Left + Round((StrafschopAfstand - Doelcirkel) * Schalingsfactor);
      Veld.LH.DoelCirkel.Bottom := MM.y + Round(DoelCirkel * SchalingsFactor);
      Veld.LH.DoelCirkel.Right  := Veld.Veld.Left + Round((StrafschopAfstand + Doelcirkel) * Schalingsfactor);
      // omdat cirkela nu net ffkes de andere kant opdraaien dienen het start en eindpunt
      // verwisseld te worden op de linkerhelft
      Veld.LH.DoelCirkel.ex := Veld.LH.StrafschopGebied.Right;
      Veld.LH.DoelCirkel.ey := MM.y - round(7.312 * schalingsfactor);   // 7.312 is magisch wiskundige toverwaarde
      Veld.LH.DoelCirkel.sx := Veld.LH.StrafschopGebied.Right;
      Veld.LH.DoelCirkel.sy := MM.y + round(7.312 * schalingsfactor);   // 7.312 is magisch wiskundige toverwaarde
    
      Veld.RH.DoelCirkel.Top    := MM.y - Round(DoelCirkel * SchalingsFactor);
      Veld.RH.DoelCirkel.Left   := Veld.Veld.Right - Round((StrafschopAfstand - Doelcirkel) * Schalingsfactor);
      Veld.RH.DoelCirkel.Bottom := MM.y + Round(DoelCirkel * SchalingsFactor);
      Veld.RH.DoelCirkel.Right  := Veld.Veld.Right - Round((StrafschopAfstand + Doelcirkel) * Schalingsfactor);
      Veld.RH.DoelCirkel.sx := Veld.RH.StrafschopGebied.Left;
      Veld.RH.DoelCirkel.sy := MM.y - round(7.312 * schalingsfactor);   // 7.312 is magisch wiskundige toverwaarde
      Veld.RH.DoelCirkel.ex := Veld.RH.StrafschopGebied.Left;
      Veld.RH.DoelCirkel.ey := MM.y + round(7.312 * schalingsfactor);   // 7.312 is magisch wiskundige toverwaarde
    
    
      // Het lijken net echte vector graphics, niet ? ;-)
    end;
    
    
    
    {
      Teken een voetbalveld op een canvas
    }
    procedure TekenVoetbalVeldOpCanvas(Veld: TVoetBalVeld; C: TCanvas);
      begin
        // c.LockCanvas;
    
        // c.AntialiasingMode:= amOn;
    
        // maak het tekenveld schoon met de kleur groen.
        c.Brush.Color := clGreen;
        c.Clear;
    
        // Een willekeurige breedte van de tekenpen
        c.pen.Width := 1;
    
        // kleurinstelling van de pen
        // TIP: Als je de 'witte'lijnen niet helemaal wit maakt maar een zachtere
        // kleur groen dan steekt dat ook niet zo af en voorkomt dit opvallende
        // blokkerigheid.
        c.pen.color := $0088FF88;
    
    
        // Hier gaat het daadwerkelijk tekenen van start
        c.Rectangle(veld.Veld);                // teken veld;
        c.Ellipse(Veld.MiddenCirkel);          // teken middencirkel
        c.Line(Veld.Middenlijn);               // teken middenlijn;
    
        c.brush.color := $0088FF88;
        c.Ellipse(Veld.MiddenStip);            // teken middenstip;
        c.Brush.Color := clGreen;
    
        c.rectangle(Veld.LH.StrafschopGebied); // teken strafschopgebied op linkerhelft
        c.rectangle(Veld.RH.StrafschopGebied); // teken strafschopgebied op rechterhelft
    
        c.brush.color := $0088FF88;
        c.Ellipse(Veld.LH.StrafschopStip);     // teken strafschopstip op linkerhelft
        c.Ellipse(Veld.RH.StrafschopStip);     // teken strafschopstip op rechterhelft
        c.Brush.Color := clGreen;
    
    
        c.Rectangle(Veld.LH.DoelGebied);       // teken doelgebied op linkerhelft
        c.Rectangle(Veld.RH.DoelGebied);       // teken doelgebied op rechterhelf
    
        c.Arc
        (
          Veld.LH.DoelCirkel.Left,
          Veld.LH.DoelCirkel.Top,
          Veld.LH.DoelCirkel.Right,
          Veld.LH.DoelCirkel.Bottom,
          Veld.LH.DoelCirkel.sx,
          Veld.LH.DoelCirkel.sy,
          Veld.LH.DoelCirkel.ex,
          Veld.LH.DoelCirkel.ey
          );                                   // teken doelcirkel op linkerhelft
    
        c.Arc
        (
          Veld.RH.DoelCirkel.Left,
          Veld.RH.DoelCirkel.Top,
          Veld.RH.DoelCirkel.Right,
          Veld.RH.DoelCirkel.Bottom,
          Veld.RH.DoelCirkel.sx,
          Veld.RH.DoelCirkel.sy,
          Veld.RH.DoelCirkel.ex,
          Veld.RH.DoelCirkel.ey
          );                                   // teken doelcirkel op rechterhelft
    
        // c.UnlockCanvas;
      end;
    
    
    
    { TForm1 }
    
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      // Zeker maken dat we niet op een al te klein werkgedeelte moeten gaan tekenen
      Constraints.MinHeight  := Round(Veld_Breedte + VirtualBorderSize + Self.BorderWidth);
      Constraints.MinWidth   := Round(Veld_Lengte  + VirtualBorderSize + Self.BorderWidth);
    end;
    
    procedure TForm1.FormPaint(Sender: TObject);
    begin
      TekenVoetbalVeldOpCanvas(EenVoetbalVeld, Canvas);
    end;
    
    procedure TForm1.FormResize(Sender: TObject);
    begin
      HerSchaalVeldCoordinaten(EenVoetbalVeld, ClientWidth, ClientHeight);
    end;
    
    
    end.
    Ziet iemand nu nog steeds bloemkolen ?

    groetjes,

    Click image for larger version. 

Name:	VoetbalVeld.PNG 
Views:	24545 
Size:	54.8 KB 
ID:	6023

  14. #14
    Ziet er keurig uit Flabber.

    De maten van het veld kloppen alleen de breedte niet.

    De lengte van de velden in Nederland zijn 100 tot 105m
    de breedte is 64 tot 69m.
    Dit zijn de officiele KNVB maten.

    Bedankt.
    Geniet maar drink met je maten.

    Geen liters maar vaten!!!

  15. #15
    Dat lijkt makkelijk op te lossen.
    Code:
     Veld_Breedte             = 50.00;      // Breedte van een voetbalveld
    1+1=b

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •