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.
kev/Drawer/UCDraw/SegyReader/GraphicsWriter.cs

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();
}
}
}