2

私は学校のプロジェクトのために Lazarus で 2-3 Trees アプリケーションを書いています。

すべてが完了し、GUI で遊んでいます (良い GUI では、良い etc. Insert 関数と同じ数のポイントを取得しますが、これは奇妙ですが nvm です)。

ツリーに 10 以上のノードがある場合、300*200 の画像サイズでは十分な大きさではありません。

TForm では 300*200 のような TImage コンポーネントが必要ですが、実際には 10000 * 10000 のようになり、スクロールできます。

それは可能ですか?

ありがとう

質問をより明確にするために編集

  1. 2-3 ツリーはデータ構造です。それがどのように機能するかを紙に描くと、次のようになります http://www.cosc.canterbury.ac.nz/research/RG/alg/tree23.gif

  2. ラザロ/デルファイの真の初心者として(ラザロでそれを行う必要があります)、このコードを使用して描画します(質問に答える必要があるとは思わない場合でも):

    procedure TStrom.Paint(Image: TImage);
    

    var C: TCanvas;

    プロシージャ Paint1(V: TNode; 幅、X、Y: 整数); 始める

    if V.L <> nil then    //left child
    begin
      C.MoveTo(X, Y);
      C.LineTo(X - Width div 3, Y + 50);
      Paint1(V.L, Width div 3, X - Width div 3, Y + 50);
    end;
    
    if V.S <> nil then    //middle child 
    begin
      C.MoveTo(X, Y);
      C.LineTo(X + Width div 3, Y + 50);
      Paint1(V.S, Width div 3, X + Width div 3, Y + 50);
    end;
    
    if V.P <> nil then     //right child
    begin
      C.MoveTo(X, Y);
      C.LineTo(X + Width div 3 + Width div 3, Y + 50);
      Paint1(V.P, Width div 3, X + Width div 3 + Sirka div 3, Y + 50);
    end;
    
    if V.isLeaf then
    begin
      C.Ellipse(X - 15, Y - 15, X + 15, Y + 15);
      C.TextOut(X - 3, Y - 8, IntToStr(V.Info1));
    end
    else
    begin
      C.Rectangle(X - 15, Y - 15, X + 15, Y + 15);
      C.TextOut(X - 7, Y - 8, IntToStr(V.Info1));
      C.Rectangle(X + 15, Y - 15, X + 50, Y + 15);
      if V.Info2 <> 0 then
        C.TextOut(X + 27, Y - 8, IntToStr(V.Info2));
    end;
    
  3. 描画機能はうまく機能しますが、高さ 3+ のノードの一部 (ほとんど) が他のノードに描画されるため、見栄えが悪くなります。ノードは別のノード上にあり、その隣に 20 ピクセルありません。

  4. 木が描かれている絵をすごく大きくしようと思ったのですが、小さな「パネル」に収まってしまいました。このように: TImage は実際には 1000*1000 になりますが、フォームではその一部しか見ることができません。この部分には水平スクロール バーと垂直スクロール バーがあるため、画像をスクロールしてセクションに何が描かれているかを確認できます。(ウェブブラウザをスクロールしてページの下部を見るときのように:))

  5. 他のコードを使用することは許可されておらず、lazarus コンポーネントに組み込まれているだけです。(また、新しいコンポーネントを作成することも許可されていません -> 理由がわかりません)

  6. これがどのように行われるかについてはまだ興味がありますが、アプリケーションにはもう必要ありません (2 番目のモニターをインストールして、それが役立つかどうかを確認したので、ペイント メソッドを掘り下げると思います)。少し :-) )

4

2 に答える 2

3

編集により、リンク先の例の最後のツリーのような回路図を描きたいことがより明確になります。

あなたのコードから、すべてのノード、子、葉を単一のキャンバスに描画していることを理解しています。その結果、1 つの大きなイメージ/ビットマップが作成されます。では、横にスクロール バーがある大きな画像の一部だけを表示するにはどうすればよいでしょうか。

明らかな選択は、 を のTPaintBox上に配置することTScrollBoxです。Lazarus のコンポーネントのデフォルト スイートはわかりませんが、両方とも存在するはずです。ビジュアル ツリーの境界と同じサイズのペイント ボックスを指定すると、スクロール バーが自動的に表示されます。

絵の具箱には、OnPaintに絵を描いて絵を描くイベントがありますPaintBox.Canvas。これを最適化するには、描画をPaintBox.Canvas.ClipRect(スクロール ボックス内に表示されるペイント ボックスの部分) に制限することができますが、隣接するノード間の適切な距離を計算することが既に困難であるため、それは難しいと思われます。(それについて: ツリー全体の最大の幅と高さは、全体の深さの関数であると予想していますが、簡単に誤解される可能性があります。)

Lazarus に がない場合は、プロパティも持つ をTPaintBox使用します。欠点は、すべての描画操作が 1 つの大きな内部ビットマップに「格納」されることです。これにより、ツリーが拡張しすぎると、メモリまたはリソースの問題が発生する可能性があります。TImageCanvasTImage

于 2013-01-16T18:04:05.660 に答える
1

すべての画像を 1 つの大きな画像に結合できますか? もしそうなら、このコンポーネントがあなたの質問に答えるかもしれません。

の子孫でありTGraphicControl、アニメーション化されたズームが可能です。選択長方形をドラッグしてグラフィックの一部をズームインし、ダブルクリックしてグラフィック全体をズームアウトします。パン操作を実行できるように更新する必要がある場合は、撮影してください。

于 2013-01-16T07:33:49.260 に答える