AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

3-dimensional array to list?

Ein Thema von WojTec · begonnen am 1. Jun 2011 · letzter Beitrag vom 1. Jun 2011
Antwort Antwort
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#1

3-dimensional array to list?

  Alt 1. Jun 2011, 12:40
Delphi-Version: 2010
Hello,

I have type:

TMatrix = array of array of array of Byte;

I neec it to process graphic, so, array I think is the worst idea. I thought about list: TList<Byte>, how I can make TMatrix list based?
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: 3-dimensional array to list?

  Alt 1. Jun 2011, 12:42
Why not a list of vertices?
Markus Kinzler
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#3

Re: 3-dimensional array to list?

  Alt 1. Jun 2011, 12:52
What you mean? Could you expand your idea?

BTW: I need it to make Perlin noise.

Geändert von WojTec ( 1. Jun 2011 um 12:56 Uhr)
  Mit Zitat antworten Zitat
blackfin
(Gast)

n/a Beiträge
 
#4

AW: 3-dimensional array to list?

  Alt 1. Jun 2011, 13:18
Why is an array the "worst implementation"?
In most 3D engines, a vector matrix is described and implemented like this:

TVector3f = array[0..2] of single;
TMatrix3f = array[0..2] of TVector3f;

Geändert von blackfin ( 1. Jun 2011 um 13:26 Uhr)
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#5

Re: 3-dimensional array to list?

  Alt 1. Jun 2011, 14:12
See yourself:

Delphi-Quellcode:
{ Copyright (C) 2000 Michael Hansen. All Rights Reserved. }

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls,
  ExtCtrls, ComCtrls, GR32_Image, Spin;

type
  TForm1 = class(TForm)
    Draw: TButton;
    NoiseGen: TButton;
    NoiseRadio: TRadioGroup;
    SmoothRadio: TRadioGroup;
    ViewCombo: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    Image321: TImage32;
    SpinEdit1: TSpinEdit;
    procedure FormCreate(Sender: TObject);
    procedure DrawClick(Sender: TObject);
    procedure NoiseGenClick(Sender: TObject);
    procedure Mix;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure NoiseRadioClick(Sender: TObject);
    procedure SmoothRadioClick(Sender: TObject);
    procedure ViewComboChange(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

type
  TRGBTripleArray = array [0 .. 32767] of TRGBTriple;

var
  Bitmap: TBitmap;
  YLine: ^TRGBTripleArray;
  Noise: array of array of array of Byte;
  Layers: array of array of array of Byte;
  InitDone: Boolean = False;

  { Max shr CLayer MUST be > 1 else program exits.
    In other words:  if Max div CLayer*2^CLayer > 1 then close }

  CLayer: Byte = 7; { Actual Layers = CLayer+1 }
  Max: Word = 255; { Actual Size = (Max+1)*(Max+1) }

  { Grain or MixDown Factor, thats like a layers opasity
    in photoshop,127=50% Opaque and 255=100% Opaque.
    Change the grainess with this value. > 127 = more grain. }

  Grain: Byte = 127;

{$R *.DFM}

function freq(xy, layer: Word): Word;
begin
  Result := xy shr layer;
end;

procedure TForm1.Mix;
var
  x, y: Word;
  c, l: Byte;
begin
  l := ViewCombo.ItemIndex;
  if l = 0 then
  begin
    for y := 0 to Max do
    begin
      YLine := Bitmap.Scanline[y];
      for x := 0 to Max do
      begin
        c := Layers[0, x, y];
        for l := 1 to CLayer do
          c := ((c * Grain) + (Layers[l, x, y] * not Grain)) shr 8;
        FillChar(YLine[x], 3, c);
      end;
    end
  end
  else
  begin
    for y := 0 to Max do
    begin
      YLine := Bitmap.Scanline[y];
      for x := 0 to Max do
      begin
        c := Layers[l - 1, x, y];
        FillChar(YLine[x], 3, c);
      end;
    end;
  end;
  Image321.Bitmap.Assign(Bitmap);
end;

procedure Init(NumberOFLayers: byte);
var
  xy, y: Word;
  l: Byte;
begin
  SetLength(Noise, NumberOFLayers + 1);
  SetLength(Layers, NumberOFLayers + 1);

  for l := 0 to NumberOFLayers do
  begin
    xy := freq(Max, l);
    SetLength(Noise[l], xy + 1);
    SetLength(Layers[l], Max + 1);
    for y := 0 to xy do
      SetLength(Noise[l, y], xy);
    for y := 0 to Max do
      SetLength(Layers[l, y], Max + 1);
  end;
end;

procedure InterpolateRect(Rect: TRect; v1, v2, v3, v4: byte; layer: byte);
var
  c, x, y, dx, dy, dxy, dxX, dyY: Word;
begin
  { Interpolation between the values v1..v4 in the size of rect }
  with Rect do
  begin
    dx := Right - Left;
    dy := Bottom - Top;
    dxy := dx * dy;
    for y := 0 to dy do
    begin
      dyY := dy - y;
      for x := 0 to dx do
      begin
        dxX := dx - x;
        c := (v1 * dyY * dxX) div dxy + (v2 * dyY * x) div dxy + (v3 * y * dxX)
          div dxy + (v4 * y * x) div dxy;
        Layers[layer, Left + x, Top + y] := c;
      end;
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  x: Byte;
begin
  if Max shr CLayer < 1 then
    exit; { see introduction }
  Bitmap := TBitmap.Create;
  Bitmap.PixelFormat := pf24bit;
  Bitmap.SetSize(Max + 1, Max + 1);
  Init(CLayer);
  ViewCombo.Items.Add('Mixed Layers');
  for x := 0 to CLayer do
    ViewCombo.Items.Add('Layer ' + IntToStr(x + 1));
  NoiseRadio.ItemIndex := 0;
  SmoothRadio.ItemIndex := 0;
  ViewCombo.ItemIndex := 0;
  InitDone := true;
  NoiseGen.Click;
end;

procedure TForm1.DrawClick(Sender: TObject);
var
  x, y: Word;
  l, cl: Byte;
  sc: Single;
begin
  Screen.Cursor := crHourGlass;
  { No Interpolation and layer[0] fill }
  for l := 0 to CLayer do
    for x := 0 to Max do
      for y := 0 to Max do
        Layers[l, x, y] := Noise[l, freq(x, l), freq(y, l)];
  { Interpolation }
  if SmoothRadio.ItemIndex = 0 then
  begin
    for l := 1 to CLayer do
    begin
      y := 0;
      cl := freq(Max, l);
      sc := Max / cl;
      repeat
      begin
        x := 0;
        repeat
        begin
          InterpolateRect(Rect(Round(x * sc), Round(y * sc),
              Round((x * sc) + sc), Round((y * sc) + sc)), Noise[l, x, y],
            Noise[l, x + 1, y], Noise[l, x, y + 1], Noise[l, x + 1, y + 1], l);
          Inc(x);
        end;
        until x = cl;
        Inc(y);
      end;
      until y = cl;
    end;
  end;
  Mix;
  Screen.Cursor := crDefault;
end;

procedure TForm1.NoiseGenClick(Sender: TObject);
var
  x, y, l: Word;
begin
  Randomize;
  { Grayscale noise }
  if NoiseRadio.ItemIndex = 0 then
    for l := 0 to CLayer do
      for x := 0 to freq(Max, l) do
        for y := 0 to freq(Max, l) do
          Noise[l, x, y] := Random(32768);
  { Monochrome noise }
  if NoiseRadio.ItemIndex = 1 then
    for l := 0 to CLayer do
      for x := 0 to freq(Max, l) do
        for y := 0 to freq(Max, l) do
          if Random(32768) > 16384 then
            Noise[l, x, y] := 255
          else
            Noise[l, x, y] := 0;
  Draw.Click;
  // ViewCombo.ItemIndex:=0
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  { Release memory used }
  Finalize(Layers);
  Finalize(Noise);
  YLine := nil;
  Bitmap.Free
end;

procedure TForm1.NoiseRadioClick(Sender: TObject);
begin
  if InitDone then
    NoiseGen.Click
end;

procedure TForm1.SmoothRadioClick(Sender: TObject);
begin
  if InitDone then
    Draw.Click
end;

procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
  Grain := SpinEdit1.Value;
  Mix;
end;

procedure TForm1.ViewComboChange(Sender: TObject);
begin
  if InitDone then
    Mix
end;

end.
When I want to use bigger bitmap, AVs are raised. So, this is reason I'm looking for better structure than array.
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#6

AW: 3-dimensional array to list?

  Alt 1. Jun 2011, 14:24
Eh..if you get Avs, its not a problem of arrays in general, its a problem of your memorymanagement o.O(someone correct me if iam wrong)
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#7

Re: 3-dimensional array to list?

  Alt 1. Jun 2011, 15:53
H,. but in this exapmle if I set larger bitmap size, AV is here, if smaller is ok.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#8

AW: 3-dimensional array to list?

  Alt 1. Jun 2011, 16:32
Arrays are already the most compact structure here. And it's not even the arrays (memorywise) that are your problem, the problem is, that the algorithm is constrained to a certain size. (You didn't write it yourself i guess.)

Currently, your arrays are sized like this:
Noise: 8*127*127
Layers: 8*128*128
These are fixed values, and do not depend on image size anywhere in the code you've shown. But because Layers[a, x, y] sometimes is accessed with image width and height for x and y, you run out of bounds on images larger than 128 pixel in any axis. (InterpolateRect() is such a candidate for example, if the passed Rect is >128².) You either need to make the current algo depend on image size, or upsample from 128x128. A list however, won't do anything at all. Especially nothing good.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium ( 1. Jun 2011 um 16:37 Uhr)
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#9

Re: 3-dimensional array to list?

  Alt 1. Jun 2011, 18:07
But this is problem I don;t know how to make it workable for any size
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz