You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
8.5 KiB
C#
234 lines
8.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Unplugged.Segy
|
|
{
|
|
public class GraphicsWriter
|
|
{
|
|
private float _TraceWidth = 10;
|
|
private Pen _DrawPen = Pens.Black;
|
|
public Pen DrawPen { get=>_DrawPen; set=>_DrawPen=value; }
|
|
public float TraceWidth { get => _TraceWidth; set => _TraceWidth=value; }
|
|
public Brush DrawBrush { get => drawBrush; set => drawBrush=value; }
|
|
private int wholeWidth;
|
|
private int wholeHeight;
|
|
|
|
private int SampleInteral;
|
|
private int SampleNumber;
|
|
private Brush drawBrush = Brushes.Black;
|
|
private static ValueRange FindRange(IEnumerable<ITrace> traces)
|
|
{
|
|
var min = float.MaxValue;
|
|
var max = float.MinValue;
|
|
foreach (var trace in traces)
|
|
foreach (var value in trace.Values)
|
|
{
|
|
if (float.IsInfinity(value)) continue;
|
|
if (value<min) min=value;
|
|
if (value>max) max=value;
|
|
}
|
|
return new ValueRange { Min=min, Max=max, Delta=max-min };
|
|
}
|
|
public Image WriteImg(int width, ISegyFile segyFile)
|
|
{
|
|
int nBorderLeft = 100;
|
|
wholeWidth=width+nBorderLeft;
|
|
//float fZoom = 1.0f;
|
|
//fZoom=Math.Min(width/symbol.Width, height/symbol.Height);
|
|
|
|
SampleNumber=segyFile.Header.SampleNumber;
|
|
SampleInteral=segyFile.Header.SampleInteral;
|
|
int nTraceCount = segyFile.Traces.Count();
|
|
if (nTraceCount<=0) { return null; }
|
|
//wholeHeight = segyFile.Traces[0].Values.Count;
|
|
wholeHeight=(int)TransDongying(SampleNumber);
|
|
|
|
TraceWidth=(float)wholeWidth/(float)nTraceCount;
|
|
Color bkColor = Color.Transparent;
|
|
//int fClientWidth = width, fClientHeight = 0;
|
|
Bitmap dst = new Bitmap(wholeWidth, wholeHeight);//, PixelFormat.DontCare);
|
|
Graphics g = Graphics.FromImage(dst);
|
|
// 设置高质量插值法
|
|
g.InterpolationMode=System.Drawing.Drawing2D.InterpolationMode.Default;
|
|
//设置高质量,低速度呈现平滑程度
|
|
g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.Default;
|
|
g.CompositingQuality=System.Drawing.Drawing2D.CompositingQuality.Default;
|
|
// 消除锯齿
|
|
g.SmoothingMode=SmoothingMode.Default;
|
|
g.Clear(bkColor);
|
|
|
|
//Matrix mx = new Matrix();
|
|
//mx.Translate(-fClientWidth/2f, -fClientHeight/2f, MatrixOrder.Append);
|
|
//mx.Rotate(rotation, MatrixOrder.Append);
|
|
//mx.Translate(fClientWidth/2f, fClientHeight/2f, MatrixOrder.Append);
|
|
//mx.Scale(fZoom, fZoom, MatrixOrder.Append);
|
|
//g.Transform=mx;
|
|
|
|
//SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 255));
|
|
//g.FillRectangle(brush, ClientRectangle);
|
|
g.TranslateTransform(nBorderLeft, 0);
|
|
Draw(g, segyFile);
|
|
// 绘制边框
|
|
g.DrawLine(DrawPen, 0, 0, 0, wholeHeight);
|
|
|
|
int nScaleHStep = 20;
|
|
//float fScaleHSpace = TraceWidth*nScaleHStep;
|
|
Font ftScaleH = new Font("宋体", 20);
|
|
for (int i = 0; i<nTraceCount; i+=nScaleHStep)
|
|
{
|
|
float fX = TraceWidth* i;
|
|
float fY = 0;
|
|
g.DrawString(i+"", ftScaleH, Brushes.Black, fX, fY);
|
|
}
|
|
|
|
g.ResetTransform();
|
|
// 画刻度
|
|
int nScaleVSpace = 250;
|
|
int nScaleVCount = wholeHeight/nScaleVSpace;
|
|
int nScaleV = 0;
|
|
Font ftScale = new Font("宋体", 25);
|
|
for (int i=0;i<=nScaleVCount;i++)
|
|
{
|
|
g.DrawLine(DrawPen, nBorderLeft-25, nScaleV, nBorderLeft, nScaleV);
|
|
|
|
SizeF sizeF = g.MeasureString(nScaleV+"", ftScale);
|
|
float fX = nBorderLeft-sizeF.Width+1;
|
|
float fY = nScaleV-sizeF.Height;
|
|
g.DrawString(nScaleV+"", ftScale, Brushes.Black, fX, fY);
|
|
nScaleV =i*nScaleVSpace;
|
|
}
|
|
|
|
|
|
|
|
return dst;
|
|
}
|
|
public virtual void Draw(Graphics g, ISegyFile segyFile)
|
|
{
|
|
if (segyFile.Traces == null)
|
|
{
|
|
return;
|
|
}
|
|
dynamic range = FindRange(segyFile.Traces);
|
|
var inlineNumbers = GetInlineNumbers(segyFile);
|
|
if (inlineNumbers.Count()==1)
|
|
Draw(g, segyFile.Traces, range);
|
|
else
|
|
{
|
|
Draw(g, segyFile.Traces, range);
|
|
}
|
|
// dynamic range = FindRange(segyFile.Traces);
|
|
//WriteBitmapPerInline(segyFile, path, inlineNumbers, range);
|
|
//}
|
|
}
|
|
private void Draw(Graphics g, IEnumerable<ITrace> traces, ValueRange range)
|
|
{
|
|
int nCOunt = traces.Count();
|
|
for (int i=0;i<nCOunt; i++)
|
|
{
|
|
Draw(g,i, traces.ElementAt(i), range);
|
|
}
|
|
}
|
|
private void Draw(Graphics g,int traceIndex, ITrace trace, dynamic range)
|
|
{
|
|
float fA = 4f;// 振幅系数
|
|
float fOffsetX = (traceIndex+0.5f)*TraceWidth;
|
|
int nCount = trace.Values.Count;
|
|
PointF[] lstValue = new PointF[nCount];
|
|
float fX = 0;
|
|
List<PointF> lstFill = new List<PointF>();
|
|
float fV0 = fOffsetX+(-range.Min/range.Delta*TraceWidth-0.5f*TraceWidth)*fA;
|
|
float fLastX = 0;
|
|
float fLastY = 0;
|
|
for (int i = 0; i<nCount; i++)
|
|
{
|
|
fLastX=trace.Values[i];
|
|
fLastY=TransDongying(i);
|
|
// fLastY=i;
|
|
if (float.IsInfinity(fLastX))
|
|
{
|
|
fLastX=0;
|
|
}
|
|
fX=fOffsetX+((fLastX-range.Min)/range.Delta*TraceWidth-0.5f*TraceWidth)*fA;
|
|
|
|
lstValue[i]=new PointF(fX, fLastY);
|
|
if (trace.Values[i]>0)
|
|
{
|
|
if (lstFill.Count==0&&i>0)
|
|
{
|
|
float fY;
|
|
CrossByX(lstValue[i-1], lstValue[i], fV0, out fY);
|
|
lstFill.Add(new PointF(fV0, fY));
|
|
}
|
|
lstFill.Add(new PointF(fX, fLastY));
|
|
}
|
|
else
|
|
{
|
|
if (lstFill.Count>0)
|
|
{
|
|
float fY;
|
|
CrossByX(lstValue[i-1], lstValue[i], fV0, out fY);
|
|
|
|
lstFill.Add(new PointF(fV0, fY));
|
|
g.FillPolygon(DrawBrush, lstFill.ToArray());
|
|
lstFill.Clear();
|
|
}
|
|
}
|
|
}
|
|
//string ssLine = Pts2String(new List<PointF>(lstValue));
|
|
g.DrawLines(DrawPen, lstValue);
|
|
}
|
|
public float TransDongying(int traceIndex)
|
|
{
|
|
int t = traceIndex;
|
|
double dD = (Math.Exp(0.000244*t)-1)*3846.1538;
|
|
return (float)dD;
|
|
}
|
|
public static bool CrossByX(PointF pt1, PointF pt2, float fX, out float fY)
|
|
{
|
|
fY=0f;
|
|
if ((pt1.X-fX)*(pt2.X-fX)<=0)
|
|
{
|
|
if (pt1.Y==pt2.Y)
|
|
{
|
|
fY=pt1.Y;
|
|
}
|
|
else
|
|
{
|
|
fY=((fX-pt1.X)/(pt2.X-pt1.X))*(pt2.Y-pt1.Y)+pt1.Y;
|
|
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
private float TransValue(float souceValue, float offsetX, float width, ValueRange range)
|
|
{
|
|
return offsetX+(range.Delta/width)*(souceValue-range.Min);
|
|
}
|
|
private static IEnumerable<int> GetInlineNumbers(ISegyFile segyFile)
|
|
{
|
|
return segyFile.Traces.Select(t =>
|
|
{
|
|
if (t.Header==null)
|
|
return 0;
|
|
return t.Header.InlineNumber;
|
|
}
|
|
).Distinct();
|
|
}
|
|
public static string Pts2String(List<PointF> pts)
|
|
{
|
|
StringBuilder strb = new StringBuilder();
|
|
for (int i = 0; i<pts.Count; i++)
|
|
{
|
|
strb.Append(pts[i].X+","+pts[i].Y+"\r\n");
|
|
}
|
|
return strb.ToString();
|
|
}
|
|
}
|
|
}
|