0

2Dグラフィックペインで信号をスケーリングする方法を見つけるために頭を悩ませています。ストーリーは次のとおりです。アプリケーションをマイクロコントローラーに接続し、一定の間隔でデータ値(電圧ポイント)を読み取ります。これをグラフィックペインに描画します。例:

ここに画像の説明を入力してください

したがって、時間0で表示される画像では、電圧も0であり、これが続きます。6つのデータポイントの後で、ペインをクリアしてすべてをやり直します。

問題は、通常のデカルトグラフのように、グラフィックペインの中央を信号0にすることを念頭に置いて、この電圧をピクセル値に変換するにはどうすればよいかということです。この場合、誰かがスケーリングアルゴリズムを理解するのを手伝ってくれませんか?

4

2 に答える 2

1

Seems like simple math: just add the width/2 to all X coordinates which you are passing into drawing functions. Suppose you have an array of 6 points you can do the following:

var g = this.CreateGraphics();
var points = new Point[6]{new Point(0, 0), new Point(10, 10), new Point(30, 0), new Point(40,20), new Point(50, 0), new Point(60,30)};
for (int i = 0; i < points.Length-1; i++)
{
    g.DrawLine(Pens.Black, points[i].X + Width / 2, Height / 2 - points[i].Y, points[i + 1].X + Width / 2, Height / 2 - points[i + 1].Y);
}

Alternatively you can invoke TranslateTransform function to move all further drawing to some amount by X and Y axes. Example:

var g = this.CreateGraphics();
var points = new Point[6]{new Point(0, 0), new Point(10, 10), new Point(30, 0), new Point(40,20), new Point(50, 0), new Point(60,30)};
g.TranslateTransform(Width / 2, 0, System.Drawing.Drawing2D.MatrixOrder.Append);
for (int i = 0; i < points.Length-1; i++)
{
    g.DrawLine(Pens.Black, points[i].X, Height / 2 - points[i].Y, points[i + 1].X, Height / 2 - points[i + 1].Y);
}
于 2012-06-03T20:41:31.750 に答える
1

たぶんこれは役に立つでしょう(スケールと変換関数が配列内のポイントを変更していることを思い出してください):

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    var points = new PointF[6] { new PointF(0, 0), new PointF(30, 3), new PointF(90, 0), new PointF(190, 3.1f), new PointF(270, -0.5f), new PointF(360, 3.5f) };

    float maxX = (from p in points select p).Max(t => t.X);
    float maxY = (from p in points select p).Max(t => t.Y);            

    float xSizeToFit = pictureBox1.Width;
    float ySizeToFit = pictureBox1.Height/2;
    float scaleX = xSizeToFit / maxX;
    float scaleY = ySizeToFit / maxY;

    // scale to fit to given size
    ScalePoints(points, scaleX, scaleY);
    // translate to center
    TranslatePoints(points, this.pictureBox1.Width / 2 - 0.5f * xSizeToFit, this.pictureBox1.Height / 2 + 0.5f * ySizeToFit);

    DrawAxis(e.Graphics, this.pictureBox1.Size);
    e.Graphics.DrawLines(Pens.Black, points);                
}

private void TranslatePoints(PointF[] points, float transX, float transY)
{
    for (int i = 0; i < points.Length; i++)
    {
        points[i].X += transX;
        points[i].Y = transY - points[i].Y;
    }
}

private void ScalePoints(PointF[] points, float scaleX, float scaleY)
{
    for (int i = 0; i < points.Length; i++)
    {
        points[i].X *= scaleX;
        points[i].Y *= scaleY;
    }
}

public void DrawAxis(Graphics g, Size size)
{
    //x
    g.DrawLine(Pens.Black, 0, size.Height / 2, size.Width, size.Height / 2);
    //y
    g.DrawLine(Pens.Black, size.Width / 2, size.Height, size.Width / 2, 0);           
}

private void pictureBox1_Resize(object sender, EventArgs e)
{
    pictureBox1.Invalidate();
}
于 2012-06-03T23:11:32.137 に答える