2016-04-04 12 views
0

私は学校の仕事のいくつかの例を作りました。スケーリンググリッドを使用した移動ポイント(リスト内のポイント)

今私は一点で立ち往生しています。相続人は、私が何をする必要があるか

(私の母国LANGで名前とCOMENTSを含むため申し訳ありません)..私は私ができる限りlitlletコードを含めるようにしようとしますが、私は何のすべての必要性を確認していない: をクリックしてポイントを追加できる「ペインティングプログラム」を手に入れた後、それぞれのラインを描画します。私はグリッドをプログラミングし、チェックボックスをチェックすると、rastr(グリッド)リスト内の最も近い可能な点を探し、その座標をマウスでペイントしようとしているポイントに適用します。

また、トラックバーの値でグリッドを拡大縮小することもできます。

ここに私の問題があります:スケーリングしているときに、グリッドでペイントされたポイントを移動する必要があります。私はgrid.X = p.X + trackbarValueの各ポイントに対してただ単に行うことができないので、私は手がかりがありません。 (getingエラー)ここで

は、グリッドや塗装のために私のコードです:ここでは

List<Point> rastr = new List<Point>(); //rastr means grid 
List<Point> body = new List<Point>(); //painting poits 

    private void panel1_Paint(object sender, PaintEventArgs e) 
    { 
      Graphics kp = e.Graphics; 
      foreach (Point p in body) 
      { 
       kp.FillEllipse(st, p.X-s/2, p.Y-s/2, s, s); 
      } 
      //double buffer nezapomenout 
      if (body.Count>1) 
      { 
       kp.DrawLines(pero, body.ToArray());//to array prevedeni na pole 
      } 
      for (int x = 0; x < panel1.Width; x += trackBarGrid.Value) 
       for (int y = 0; y < panel1.Height; y += trackBarGrid.Value) 
       { 
        if (showGrid == true) 
        { 
         kp.FillEllipse(grid, x-2, y-2, 4, 4); 
        } 
        Point gridpoint = new Point(x,y); 
        rastr.Add(gridpoint); 
       } 
     } 

は、グリッド内の最も近いものを探していると、その後の座標適用:私のトラックバーイベントも

private void panel1_MouseClick(object sender, MouseEventArgs e) 
    { 
     if (useGrid == true) 
     { 
      //rozjedu cykly abych nasel nejblizsi bod (porovnavat jednotlivy koordinace) 
      foreach (Point p in rastr) 
      { 
       if (e.Location.X - p.X < trackBarGrid.Value/2) //kdyz odecteme pozici bodu v listu rastr.x od pozice x kliknuti nesmi byt vetsi nez polovina delky odsazeni rastrovych bodu 
        if (e.Location.Y - p.Y < trackBarGrid.Value/2) // to same jen s pozici Y 
        { 
         Point zapsat = new Point(p.X, p.Y); 
         body.Add(zapsat); //od tyhle pozice najit nejblizsi point v gridu 
         break;//bod jsme uspesne nasli. Nyni musime cyklus uzavrit aby se nezacli pridavat body ktere nechceme 
        } 
      } 
      panel1.Refresh(); 
     } 
     else { 
      body.Add(e.Location); 
      panel1.Refresh(); 
     } 
    } 

を:

private void trackBarGrid_Scroll(object sender, EventArgs e) 
    { 
     rastr.Clear(); 
     panel1.Refresh(); 
    } 

そしてこの

の私の貧しい試み
private void trackBarGrid_Scroll(object sender, EventArgs e) 
    { 
     foreach (Point p in rastr) 
     { 
      p.X += TrackBarValue; 
      p.Y += TrackBarValue; 
     } 
     panel1.Refresh(); 
    } 

最後に、「フリーハンド」の絵を保持する必要はありません。私はそのグリッドを使うことができます。ここで

は、いくつかの写真は

Before scaling

After scaling

+0

私は必死に助けてください:D –

+0

1)あなたの質問を適切な英語に編集してください。これはプロのアーカイブです。 2)あなたのポイントのコーディネートを拡大するには、乗算する必要がありますが、追加する必要はありません。倍率を知っていなければなりません(x方向およびy方向に大きく縮尺を変えた場合)。そして、古い値に倍率を掛けて新しいポイントを取得できます。 – TaW

答えて

1

を掛けるあなたのグラフィックをスケーリングすることを選んだことができる2つの方法がありますだけであること。 1つは非常にシンプルで、もう少し複雑です。ここで

は単純なものである:

単にPaintイベントの先頭にこれを追加します。

float scale = trackBar1.Value/100f; 
if (scale == 0) scale = 1; 
e.Graphics.ScaleTransform(scale, scale); 

これは少し複雑に見えますがPaintイベントがあるときTrackBarは値を持ちません最初に呼ばれた。

Graphicsオブジェクト自体がスケールされ、を描画すると、のすべてが縮尺されます。

これは本当に簡単でした。

考えられる可能性のある問題の1つは、Penの幅を含むすべてが拡大縮小されることです。

あなたの質問に、より複雑な方法のために行く、それではも同様ということをやられた..:

まず我々はTrackBarValueにaccodingポイントをスケーリング機能を作成します。ここでは、次のとおりです。

PointF scaledPoint(PointF pt, float scale, bool unscale) 
{ 
    if (unscale) return new PointF(pt.X/scale, pt.Y/scale); 
    else return new PointF(pt.X * scale, (pt.Y * scale)); 
} 

2つのことは、注目に値する:

  • 機能は、実際にPointFないPointで動作します。スケーリングが失われてはならないので、これは本当に重要です精度! 5%から33%に戻って、もう一度バックアップすると5に戻るのではなく、3に戻ってしまいます!

  • ポイントからスケーリングを削除する追加のパラメータがあります。私たちは現時点でそれを必要としません。しかし、あなたがスケーリングがオンになっているときに、MouseClickからポイントをキャッチしたいと思うでしょう!

ここでポイントリストの縮尺を変更します。私たちは、多分このように、直接それを行うことができ

for (int p = 0; p < body.Count; p++) 
    body[p] = scaledPoint(body[p], scale, false); 

を、これは動作しますがされては厄介なに問題があります:私たちはTrackBarを移動すると、それはreapetedlyが成長スケーリング係数を適用ます。これは、グラフィックスがより大きくなることを意味します速くて速い ..いいえ。我々はbodyOにポイントを追加けど身体にbodyとスケールbodyOで描く意味

代わりに、私たちは

..維持する必要が原点値と第二List<PointF> bodyOを作成..:

void scalePoints(float scale) 
{ 
    for (int p = 0; p < body.Count; p++) 
     body[p] = scaledPoint(body0[p], scale, false); 
} 

は、私たちはあなたのコードのようにほとんどを呼び出す:

private void trackBar1_Scroll(object sender, EventArgs e) 
{ 
    scalePoints(trackBar1.Value/100f); 
    panel1.Refresh(); 
} 

が、これは01でどのように機能するかを見てみましょうイベント:

private void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    float scale = trackBar1.Value/100f; 
    if (scale == 0) scale = 1; 

    bool showGrid = true; // inserted for testing 

    // these graphics work with the scaled points: 
    foreach (PointF pt in body) e.Graphics.FillEllipse(Brushes.Red, 
            pt.X - 2, pt.Y - 2, scale * 4, scale * 4); 
    if (body.Count > 1) e.Graphics.DrawLines(Pens.Black, body.ToArray()); 

    // here we don't use points but calculate the coordinates, so we need to scale 
    for (int x = 0; x < panel1.Width; x += trackBar2.Value) 
     for (int y = 0; y < panel1.Height; y += trackBar2.Value) 
     { 
      if (showGrid == true) 
      { 
       e.Graphics.FillEllipse(Brushes.Gray, 
          scale * (x - 2), scale * (y - 2), scale * 4, scale * 4); 
      } 
      // Point gridpoint = new Point(x, y); // not sure what you do here..? 
      // rastr.Add(gridpoint); // maybe add the point scaled? 
     } 
} 

ポイントのサイズも同様に拡大しました。ところで、両方のバージョンがあなたにもPenを拡張しなければならないすべて同じに見えるように:

using (Pen pen = new Pen(somecolor, penWidth * scale)) 

最後に、ここでは、MouseClickとの新しいポイントを追加する方法です:

private void panel1_MouseClick(object sender, MouseEventArgs e) 
{ 
    body0.Add(scaledPoint(e.Location, trackBar1.Value/100f, true)); 
    body.Add(e.Location); 
    panel1.Invalidate(); 
} 

我々はそれを追加しますスケーリングされたリストに現在「画素サイズ」と現在のスケーリングを逆にし、そのまま、すなわちbodyO元のリストに..

enter image description hereenter image description here

Btw:多くのグリッドポイントはDoubleBufferingなしでしばらく時間がかかります。これは...いくつかのちらつきを作成しますので、DoubleBufferingPanelサブクラスを使用するか:

class DrawPanel : Panel 
{ 
    public DrawPanel() 
    { DoubleBuffered = true; } 
} 

か(推奨)Pictureboxのために行きます!

+0

WOW man:Dそれは見えませんでした。もう私の仕事ではないような気がするxDありがとう!感謝します!私はそれを動作させるなら、できるだけ早くタイプします。 –

+0

ダメは疲れて失われました:Dこれは最初のエラーです。 http://picpaste.com/awdawdawd-BKzQmZVG.JPG –

+0

Hehe、それをすべてコピーする必要はありません;-) - ノート私は質問を編集するまでグリッドのことをあまり理解していませんでした。だからあなたのためにかなりの仕事が残っています。 – TaW

0

..です私は何とか、それらを編集しに戻ってそれらを置くそのリストOUTAそれらのポイントを得ることができた。あなたは、私がちょうど持って言ったように、それらのスケーリングファクタを把握する。すでに移動していますが、グリッドには対応していません。私は私の英語のために申し訳ありません私はそれをさらに修正する可能性はありません参照してください:D申し訳ありません...私は助けてくれる私を助けてくれる;((プロフェッショナルなアーカイブノートについてちょっと笑った) いくつかのpplポストここではこれよりもさらに悪い質問:DのとにかくのTHXは再びちょっとそれを自分で解決 事:)

private void trackBarGrid_Scroll(object sender, EventArgs e) 
     { 
      if (trackBarGrid.Value > trackbarval) 
      { 
       for (int i = 0; i < body.Count; i++) 
       { 
        Point point = body[i]; 
        point.X += trackBarGrid.Value - trackbarval; 
        point.Y += trackBarGrid.Value - trackbarval; 
        body[i] = point; 
       } 
      } 
      else if (trackBarGrid.Value < trackbarval) 
      { 
       for (int i = 0; i < body.Count; i++) 
       { 
        Point point = body[i]; 
        point.X -= trackbarval- trackBarGrid.Value; 
        point.Y -= trackbarval- trackBarGrid.Value ; 
        body[i] = point; 
       } 
      } 
      rastr.Clear(); 
      panel1.Refresh(); 
      trackbarval = trackBarGrid.Value; 
     } 
+0

まあ、私は完璧を求めていませんでした、少しだけ努力しました。言葉は 'あなた'ではなく、 'アウト'ではなく 'アウト'などではありません。そして、あなたに良い助けを与えて下降音の危険性を減らすチャンスを増やすので、これは大きな助けとなります。あなたが進歩したことをうれしく思います。私はあなたに何か乗算をしているのを見ません。あなたが望むのであれば、私は正しい答えを投稿します。 – TaW

+0

ヒント-1トラックバーは整数を保持できるだけなので、パーセンテージとして解釈する必要があります。すなわち、倍率はtrackBar.Value/100fになります。ヒント-2:Pointの代わりにPointFを使うべきです。なぜなら、すぐに精度を失うからです。ヒント-3:良い結果を得るには、元の点を__と__の点を基準にしてリストを維持します。常にオリジナルのフォームを計算し、常にスケーリングされたリストを描画します。それ以外の場合は、上下に拡大して元に戻すことはできません。 – TaW

+0

Okey :)次に答えていただきありがとうございます。 –