私のC#WinFormsアプリケーションには、2つの曲線をホストするピクチャーボックスがあります(電圧/電流測定の結果)。X軸は電圧、Y軸は電流です。電圧軸は-5から5の範囲ですが、電流軸は-10uAから10uAの範囲のはるかに小さいスケールです。タスクは、2番目の曲線が最初の曲線の10%以内にあるかどうかを確認することです。
目視検査のために、最初の曲線(青い曲線)の周りに封筒を描画しようとしています。曲線は単なるPointF
配列です。現時点では、青い曲線の周りに正しいエンベロープを描画する方法がわからないため、実際の曲線のXポイントを元の曲線の10%で減算した結果、他の2つの曲線を描画します。もちろん、これは悪いアプローチですが、少なくとも曲線の特に垂直な部分では機能します。ただし、下の図に示すように、曲線が非垂直セクションにあるとすぐに、このトリックは機能しなくなります。
封筒を描くために使用しているコードは次のとおりです。
public Bitmap DrawEnvelope(double[,] pinData, float vLimit, float iLimit)
{
g = Graphics.FromImage(box);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
PointF[] u = new PointF[pinData.GetLength(0)]; //Up line
PointF[] d = new PointF[pinData.GetLength(0)]; //Down Line
List<PointF> joinedCurves = new List<PointF>();
float posX = xMaxValue * (vLimit / 100);
float minX = posX * -1;
for (int i = 0; i < pinData.GetLength(0); i++)
{
u[i] = new PointF(400 * (1 + (((float)pinData[i, 0]) + minX) / (xMaxValue + vExpand)), 400 * (1 - ((float)pinData[i, 1] * GetInvers((yMaxValue + iExpand)))));
}
for (int i = 0; i < pinData.GetLength(0); i++)
{
d[i] = new PointF(400 * (1 + (((float)pinData[i, 0]) + posX) / (xMaxValue + vExpand)), 400 * (1 - ((float)pinData[i, 1] * GetInvers((yMaxValue + iExpand)))));
}
Pen pengraph = new Pen(Color.FromArgb(50, 0 ,0 ,200), 1F);
pengraph.Alignment = PenAlignment.Center;
joinedCurves.AddRange(u);
joinedCurves.AddRange(d.Reverse());
PointF[] fillPoints = joinedCurves.ToArray();
SolidBrush fillBrush = new SolidBrush(Color.FromArgb(40, 0, 0, 250));
FillMode newFillMode = FillMode.Alternate;
g.FillClosedCurve(fillBrush, fillPoints, newFillMode, 0);
g.Dispose();
return box;
}
緑の円は自分で追加したもので、2番目の曲線(赤の曲線)が元の曲線との差が10%を超える可能性がある領域を示しています。
誰かが私を正しい方向に導いてくれたらいいのにと思いますが、元のカーブの周りに素敵なエンベロープを実現するために何を探すべきですか?
更新 私はとても初心者なので、これまでこの質問に与えられた答えを実装する方法を見つけることができません。それで、誰かがこの問題へのコーディングアプローチを少なくとも私に親切に見せてくれるかどうかを確認するために賞金を払ってください。