Avatar billede monie Nybegynder
21. april 2004 - 10:03 Der er 7 kommentarer og
1 løsning

En gennemgående streg

Se lige her:
www.sunwind.dk/vingemenu.jpg

Denne gennemgående streg profilbreden + nogle % hvordan laves den?
Den skal værer fast og skal således ikke roteres,
men værer lidt længer i begge ender af profilet. Som kan andtage forskellige bredder!

Mine koder:

function VingePkt( x, y: Real): TVingePkt;
begin
  Result.x := x;
  Result.y := y;
end;

function RotatePkt(pkt: TVingePkt; v, cx,cy: Real): TVingePkt;
const
  toPi = 2*Pi;
begin
  v := v / 360; // ingen grund til at beregne den 4 gange.
  Result.x := (pkt.x-cx)*cos(v*toPi) - (pkt.y-cy)*sin(v*toPi) + cx;
  Result.y := (pkt.y-cy)*cos(v*toPi) + (pkt.x-cx)*sin(v*toPi) + cy;
end;

// Tegner en linie på canvas fra pkt1 til pkt2.
procedure DrawLine( pkt1, pkt2: TVingePkt);
begin
  with frmProfil.Image1.Canvas do
  begin
    MoveTo( Round(pkt1.x), Round(pkt1.y));
    LineTo( Round(pkt2.x), Round(pkt2.y));

  end;
end;


// Tegn et kryds i Image1
procedure TfrmProfil.SaetKryds( center: TVingePkt; bredde: Integer);
var
  topLeft,
  topRight,
  botLeft,
  botRight: TVingePkt;
  gemtFarve:  TColor;
begin
  // skal bruge en halv
  // bredde fra center til hver side.
  bredde := bredde div 2;

  // Beregn hjoernepunkter, som var det
  // et kvadrat der skulle tegnes uden om center.
  topLeft.x := center.x - bredde;
  botLeft.x := topLeft.x;
  topLeft.y := center.y - bredde;
  topRight.y := topLeft.y;
  botRight.x := center.x + bredde;
  topRight.x := botRight.x;
  botRight.y := center.y + bredde;
  botLeft.y := botRight.y;

  // Roter krydset sammen med profilen.
  topLeft := RotatePkt( topLeft, frmProfil.seVinkel.Value, center.x, center.y);
  topRight := RotatePkt( topRight, frmProfil.seVinkel.Value, center.x, center.y);
  botLeft := RotatePkt( botLeft, frmProfil.seVinkel.Value, center.x, center.y);
  botRight := RotatePkt( botRight, frmProfil.seVinkel.Value, center.x, center.y);

  // gem den farve der normalt tegnes med.
  gemtFarve := frmProfil.Image1.Canvas.Pen.Color;
  // skift farve til roed.
  Image1.Canvas.Pen.Color := clRed;
  // tegn diagonal fra øverste ventre hjørne
  // til nederste højre.
  DrawLine( topLeft, botRight);
  // tegn digonal fra nederste venstre hjørne
  // til øverste højre hjørne.
  DrawLine( botLeft, topRight);
  // skift farve til det der normalt tegnes med.
  Image1.Canvas.Pen.Color := gemtFarve;
end;


procedure TfrmProfil.btnTegnClick(Sender: TObject);
var
  koord:  array[0..18] of TVingeKoord;
  cx,midY: Real;
  count: Integer;

begin

  fmProfilValg.StandartTekstNaca4415;
  midY := Image1.Height /1.5; // Midten af Image1

  cx := Round( Naca4415X[ High( Naca4415X) - 1 ] * zoom / 4);
  // zoom := Round( Image1.Width / X[High(X)])-1;
  // beregn "absolutte" koordinater (uden rotation).

  // tegn et kryds i (cx,midY).

  // Hvis du vil have krydset i en fast str. uanset profilets
  // str. skal du ikke gange med zoom...

  // beregn "absolutte" koordinater (uden rotation).
  koord[0].Pkt1 := VingePkt(0,midY);
  koord[0].Pkt2 := VingePkt(0,midY);
  for count := 1 to 18 do
  begin
    koord[count].Pkt1.x := Naca4415X[count]*zoom;
    koord[count].Pkt1.y := midY - Naca4415op[count]*zoom;
    koord[count].Pkt2.x := koord[count].Pkt1.x;
    koord[count].Pkt2.y := midY - Naca4415ned[count]*zoom;
  end;
  // rotér koordinater
  // vinklen bliver laest fra SpinEdit2. cy er midY. cx er midX,
  // (cx,cy) er centrum for rotation.
  for count := 0 to 18 do
  begin
    koord[count].Pkt1 := RotatePkt( koord[count].Pkt1, seVinkel.Value, cx, midY);
    koord[count].Pkt2 := RotatePkt( koord[count].Pkt2, seVinkel.Value, cx, midY);
  end;
  // tegn på canvas.
  for count := 0 to 17 do
  begin
    DrawLine( koord[count].Pkt1, koord[count+1].Pkt1);
    DrawLine( koord[count].Pkt2, koord[count+1].Pkt2);
    // Tegn 1/4 punktet
    end;
    // Hvis du vil have et større kryds, kan du ændre 2-tallet.
    SaetKryds( VingePkt( cx, midY), 2*zoom);
    // zoom := Round( Image1.Width / X[High(X)])-1;
    If (seZoom.Value = 0) then
        seZoom.Value:=7;
end;


procedure TfrmProfil.btnClearClick(Sender: TObject);
var
  r:  TRect;  // Firkanten der definerer image-vinduet.
begin
  with Image1 do
  begin
    Picture := nil; // Fjern det billede der er der.
    // prøv at finde firkanten med windows-funktionen
    if not Windows.GetClientRect(Handle, r) then
      // ellers bare brug width / height af image.
      r := Rect( 0, 0, Width, Height);
    Canvas.FillRect( r); // fyld imagevinduet med hvid.
  end;
end;


procedure TfrmProfil.FormResize(Sender: TObject);
begin
  btnClear.Click; // Clear image1
  btnTegn.Click; // Gentegn profilen.
end;


procedure TfrmProfil.btnGemJpegClick(Sender: TObject);
var
  jpgFile: TJpegImage;
begin
  // Hvis der ikke er tegnet i Image1, saa...
  // hmmm... ved ikke om det virker ??
  if Image1.Picture.Bitmap = nil then
  begin
    ShowMessage( 'Der er ikke noget at gemme !');
    Exit;
  end;

  // Vis gem-dialog. Afslut hvis bruger trykker "annuller".
  if not SavePictureDialog1.Execute then Exit;

  // brug altid try...finally obj.free
  // efter var := obj.Create.
  // Så er du sikker på at det bliver frigivet, selvom noget skulle
  // gå galt undervejs !

  // Opret et JPG-billede.
  jpgFile := TJpegImage.Create;
  try
    // hvor meget skal der komprimeres.
    jpgFile.CompressionQuality := 85;
    // tildel bitmap fra image1.
    jpgFile.Assign( Image1.Picture.Bitmap);
    // lav bitmap om til jpeg format.
    jpgFile.JPEGNeeded;
    // comprimer billedet.
    jpgFile.Compress;
    // gem den på disk.
    jpgFile.SaveToFile( SavePictureDialog1.FileName);
  finally
    jpgFile.Free;
  end;
end;


procedure TfrmProfil.btnPrintClick(Sender: TObject);
var
  scaleX, scaleY : real; //skal jo kunne holde deimalerne
  tilpasX, tilpasY : real;
  R: TRect;
begin
  if PrinterSetupDialog1.Execute then
  begin
    Printer.BeginDoc;  // **
    fmProfilValg.StandartTekstNaca4415;
  with Printer do
    try
      tilpasX:=Profilbredde[18]/185;
      tilpasY:=Profilbredde[18]/185;
      ScaleX := GetDeviceCaps(Handle, logPixelsX) / PixelsPerInch; //division der giver decimaler
      ScaleY := GetDeviceCaps(Handle, logPixelsY) / PixelsPerInch;
      R := Rect(0, 0, trunc(Image1.Picture.Width * ScaleX * tilpasX),
      trunc(Image1.Picture.Height * ScaleY * tilpasY));
      Canvas.StretchDraw(R, Image1.Picture.Graphic);  // **
    finally
    EndDoc;  // **
  end;
end;


Med venlig hilsen
Monie Jacobsen
Avatar billede dkn Nybegynder
21. april 2004 - 12:46 #1
hvis du skal slip for at bøvle med den på canvas når der skal roteres, ville jeg da bare tage en shape og ligge der.

Men det er måske ikke godtnok?
Avatar billede monie Nybegynder
21. april 2004 - 14:16 #2
Jo det var måske også en løsning.
Har ikke meget erfaring med at lave/tegne streger med delphi 6
Har du et eksempel på kode, da jeg ikke kender noget til shape?
Avatar billede dkn Nybegynder
21. april 2004 - 16:00 #3
under additinal -> Shape.

Så bare sæt den til stRectangle og giv den en højde på 1 til 2.
Avatar billede monie Nybegynder
21. april 2004 - 16:12 #4
Jeg beklager "additinal -> Shape.

Så bare sæt den til stRectangle og giv den en højde på 1 til 2.
Siger mig ikke noget, er ikke helt med, additinal -> Shape er det en komponent?


Har forsøgt mig med:

  //Venste streg
    Image1.Canvas.MoveTo(trunc(cx), trunc(midY));
    Image1.Canvas.LineTo(trunc(bredde), trunc(midY));

    //Højere streg
    //Image1.Canvas.MoveTo(trunc(cx), trunc(midY));
    //Image1.Canvas.LineTo(trunc(10), trunc(midY));


    SaetKryds( VingePkt( cx, midY), 3*zoom);
    // zoom := Round( Image1.Width / X[High(X)])-1;
    If (seZoom.Value = 0) then
        seZoom.Value:=7;
end;

Finder godt nok midden af profilet, men kan ikke få stregen
ud til yderste venstre del af profilet.

Eller til bagende af profilet, alså højer side.
Avatar billede monie Nybegynder
21. april 2004 - 16:17 #5
Ok.Shape1 komponenten
Profilet er ellers udskrev på Image1
Da jeg ikke kender Shape, vil du da ikke prøve at rette mine koder til?
Så jeg kan få noget er faring med denne komponent
Avatar billede monie Nybegynder
22. april 2004 - 07:54 #6
Hej

Med koden her:
    //Streg gennem korden
    Image1.Canvas.MoveTo(trunc(0), trunc(midY));
    Image1.Canvas.LineTo(trunc(cx*4), trunc(midY));

Indsat i proceduren herunder:

procedure TfrmProfil.btnTegnClick(Sender: TObject);
var
  koord:  array[0..18] of TVingeKoord;
  cx,midY : Real;
  count: Integer;
begin
  fmProfilValg.StandartTekstNaca4415;
  midY := Image1.Height /1.5; // Midten af Image1

  cx := Round( Naca4415X[ High( Naca4415X) - 1 ] * zoom / 4);
  // zoom := Round( Image1.Width / X[High(X)])-1;
  // beregn "absolutte" koordinater (uden rotation).
  // tegn et kryds i (cx,midY).
  // Hvis du vil have krydset i en fast str. uanset profilets
  // str. skal du ikke gange med zoom...
  // beregn "absolutte" koordinater (uden rotation).
  koord[0].Pkt1 := VingePkt(0,midY);
  koord[0].Pkt2 := VingePkt(0,midY);
  for count := 1 to 18 do
  begin
    koord[count].Pkt1.x := Naca4415X[count]*zoom;
    koord[count].Pkt1.y := midY - Naca4415op[count]*zoom;
    koord[count].Pkt2.x := koord[count].Pkt1.x;
    koord[count].Pkt2.y := midY - Naca4415ned[count]*zoom;
  end;
  // rotér koordinater
  // vinklen bliver laest fra SpinEdit2. cy er midY. cx er midX,
  // (cx,cy) er centrum for rotation.
  for count := 0 to 18 do
  begin
    koord[count].Pkt1 := RotatePkt( koord[count].Pkt1, seVinkel.Value, cx, midY);
    koord[count].Pkt2 := RotatePkt( koord[count].Pkt2, seVinkel.Value, cx, midY);
  end;
  // tegn på canvas.
  for count := 0 to 17 do
  begin
    DrawLine( koord[count].Pkt1, koord[count+1].Pkt1);
    DrawLine( koord[count].Pkt2, koord[count+1].Pkt2);
    // Tegn 1/4 punktet
    end;
    // Hvis du vil have et større kryds, kan du ændre 2-tallet.

    //Streg gennem korden
    Image1.Canvas.MoveTo(trunc(0), trunc(midY));
    Image1.Canvas.LineTo(trunc(cx*4), trunc(midY));

    SaetKryds( VingePkt( cx, midY), 3*zoom);
    // zoom := Round( Image1.Width / X[High(X)])-1;
    If (seZoom.Value = 0) then
        seZoom.Value:=7;
end;

Men hvordan får jeg, så også en streg igennem profilet (korde),
der roter med profilet?
Se evt. function RotatePkt(pkt: TVingePkt; v, cx,cy: Real): TVingePkt;

Med venlig hilsen
Avatar billede monie Nybegynder
22. april 2004 - 08:00 #7
Glemte lige at sige, at det lykkes mig,
at få en streg igennem profilets korde.

Men ønsker også en streg igennem profilet (korde),der roter med profilet?
Ligesom hæftet til profilet.
Avatar billede monie Nybegynder
23. april 2004 - 08:17 #8
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester