using OpenCvSharp;
using OTSCLRINTERFACE;
using OTSCommon.Model;
using OTSIncAReportApp.DataOperation.DataAccess;
using OTSIncAReportGraph.Controls;
using OTSModelSharp.DTLBase;
using OTSModelSharp.ServiceCenter;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using Point = System.Drawing.Point;
namespace OTSIncAReportGraph.OTSIncAReportGraphFuncation
{
public class OTSImageDisHelp
{
#region 枚举定义
///
/// 样品台X轴方向
///
enum OTS_X_AXIS_DIRECTION
{
LEFT_TOWARD = 0,
RIGHT_TOWARD = 1
}
///
/// 样品台Y轴方向
///
enum OTS_Y_AXIS_DIRECTION
{
UP_TOWARD = 0,
DOWN_TOWARD = 1
}
#endregion
#region 定义变量
public ResultFile resultFile = null;
public ParticleSegmentation m_ParticleSegmentation;
public Point OTSLeftBottomPoint;
public Point OTSRightUpPoint;
public RectangleF m_originalBackRect;
public double m_pixelSize;
private List fieldCenterList;
NLog.Logger log;
//电镜设置对象
public ServiceInterface.HardwareController m_cfun = null;
#endregion
#region 构造函数
public OTSImageDisHelp( ResultFile result)
{
resultFile = result;
m_cfun = ServiceInterface.HardwareController.GetSemController();
List fieldlist = resultFile.List_OTSField;
int fieldwidth;
SizeF s = GetFieldImageSize();
fieldwidth = (int)s.Width;
fieldCenterList = new List();
for (int i = 0; i < fieldlist.Count(); i++)
{
Point ls_point = new Point() { X = fieldlist[i].FieldPosX, Y = fieldlist[i].FieldPosY };
fieldCenterList.Add(ls_point);
}
SizeF physicalfiledsize = GetPhysicalFieldWidthAndHeight();
m_pixelSize = Convert.ToDouble(physicalfiledsize.Width) / Convert.ToDouble(fieldwidth);
OTSLeftBottomPoint = GetOTSCoordLeftBottomPoint(fieldCenterList, (int)physicalfiledsize.Width, (int)physicalfiledsize.Height);
OTSRightUpPoint = GetOTSCoordRightUpPoint(fieldCenterList, (int)physicalfiledsize.Width, (int)physicalfiledsize.Height);
m_originalBackRect = new RectangleF(0, 0, (float)((OTSRightUpPoint.X - OTSLeftBottomPoint.X)/m_pixelSize), (float)((OTSRightUpPoint.Y - OTSLeftBottomPoint.Y)/m_pixelSize));
log = NLog.LogManager.GetCurrentClassLogger();
}
#endregion
#region 封装自定义方法
private Point GetOTSCoordLeftBottomPoint(List allFldPos,int fieldwidth,int fieldheight)
{
//the ots coordinate system is always positive on the right and up direction.So the leftbottom point would be the smallest point.
//找出最小的x,y用来做偏移运算
int i_offset_x = 1000000000;
int i_offset_y = 1000000000;
//先取出最小的x,y
for (int i = 0; i < allFldPos.Count; i++)
{
if (i_offset_x > allFldPos[i].X)
{
i_offset_x = allFldPos[i].X;
}
if (i_offset_y > allFldPos[i].Y)
{
i_offset_y = allFldPos[i].Y;
}
}
return new Point(i_offset_x-fieldwidth/2, i_offset_y-fieldheight/2);//the field pos is the center point position.
}
private Point GetOTSCoordRightUpPoint(List allFldPos, int fieldwidth, int fieldheight)
{
//the ots coordinate system is always positive on the right and up direction.So the leftbottom point would be the biggest point.
//找出最小的x,y用来做偏移运算
int i_offset_x = -1000000000;
int i_offset_y = -1000000000;
//先取出最小的x,y
for (int i = 0; i < allFldPos.Count; i++)
{
if (i_offset_x < allFldPos[i].X)
{
i_offset_x = allFldPos[i].X;
}
if (i_offset_y < allFldPos[i].Y)
{
i_offset_y = allFldPos[i].Y;
}
}
return new Point(i_offset_x + fieldwidth / 2, i_offset_y + fieldheight / 2);//the field pos is the center point position.
}
public Point ConvertOTSCoordToScreenCoord( Point currenFldOTSPos)//
{
var OTSPoint=new Point(currenFldOTSPos.X - OTSLeftBottomPoint.X, currenFldOTSPos.Y - OTSLeftBottomPoint.Y);
int screenHeight = (int)m_originalBackRect.Height + (0 - (int)(Convert.ToDouble(OTSPoint.Y) / m_pixelSize));//because the screen coordinate is downward rightward positive,so we need to translate the Y coordinate of the OTS system which is upward rightward positive.
var screenPoint = new Point((int)(Convert.ToDouble(OTSPoint.X)/m_pixelSize), (int)(screenHeight));
//var curP = new Point((int)(screenPoint.X + m_wholeBackRect.X), (int)(screenPoint.Y + m_wholeBackRect.Y));
var curP = new Point((int)(screenPoint.X + m_originalBackRect.X), (int)(screenPoint.Y + m_originalBackRect.Y));
return curP;
}
public SizeF GetPhysicalFieldWidthAndHeight()
{
SizeF ret_rect = new SizeF(0, 0);
Dictionary sampleMembers = ((Dictionary)((Dictionary)resultFile.ResultInfo["Sample"])["Members"]);
Dictionary SEMDataMsr = (Dictionary)sampleMembers["SEMDataMsr"];
Dictionary msrParams = (Dictionary)sampleMembers["MsrParams"];
Dictionary imgParam = (Dictionary)msrParams["Members"];
Dictionary scanParam = (Dictionary)imgParam["ImageScanParam"];
string resolution = scanParam["ImageResolution"].ToString();
int width = Convert.ToInt32(resolution.Split('_')[1].ToString());
int height = Convert.ToInt32(resolution.Split('_')[2].ToString());
double retioOfHeightWidth =(double) height;
retioOfHeightWidth /= width;
string scanfeldsize = SEMDataMsr["ScanFieldSize"].ToString();
double d_scanFieldSize_width = Convert.ToDouble(scanfeldsize);
double d_scanFieldSize_height = 0;
if (d_scanFieldSize_width != 0)
d_scanFieldSize_height = d_scanFieldSize_width * retioOfHeightWidth;
ret_rect.Width = (int)d_scanFieldSize_width;
ret_rect.Height = (int)d_scanFieldSize_height;
return ret_rect;
}
public SizeF GetFieldImageSize()
{
SizeF s = new SizeF();
Dictionary sampleMembers = ((Dictionary)((Dictionary)resultFile.ResultInfo["Sample"])["Members"]);
//Dictionary SEMDataMsr = (Dictionary)sampleMembers["SEMDataMsr"];
Dictionary msrParams= (Dictionary)sampleMembers["MsrParams"];
Dictionary imgParam = (Dictionary)msrParams["Members"];
Dictionary scanParam = (Dictionary)imgParam["ImageScanParam"];
string resolution = scanParam["ImageResolution"].ToString();
int width = Convert.ToInt32(resolution.Split('_')[1].ToString());
int height = Convert.ToInt32(resolution.Split('_')[2].ToString());
s.Width = width;
s.Height = height;
return s;
}
#endregion
#region 电镜操作相关方法
///
/// 连接电镜,分布图使用
///
public bool ConnectToIpcSvr()
{
//和电镜建立通讯连接
return m_cfun.ConnectToIpcSvr();
}
///
/// 移动电镜到指定的X,Y坐标上,R坐标使用原先的值进行移动
///
///
///
public void MoveSemToPointXY(double in_PositionX, double in_PositionY)
{
log.Trace("Begin MoveSemToPointXY:(" +in_PositionX.ToString()+","+in_PositionY.ToString()+")");
//首先获取电镜当前的位置,并记录原R值
double ls_PositionX = 0;
double ls_PositionY = 0;
double ls_PositionR = 0;
if (m_cfun.ConnectToIpcSvr())
{
m_cfun.GetSemPositionXY(ref ls_PositionX, ref ls_PositionY, ref ls_PositionR);
}
else
{
log.Error("Failed to GetSemPositionXY");
return;
}
if (m_cfun.ConnectToIpcSvr())
{
m_cfun.MoveSEMToPoint(new Point((int)in_PositionX, (int)in_PositionY), ls_PositionR);
}
}
#endregion
#region //--------------------------------------颗粒分布图相关部份---------------------------------------------------------------------
///
/// 传入颗粒的tagid和fieldid,来获取该颗粒下对应的xray数据
///
///
///
///
///
public void GetXrayByParticleTagIDAndFieldID_ForDrawDistrbutionImageAndBSE(int in_clr_tagid, int in_clr_fieldid, out uint[] Search_xray, out uint[] Analysis_xray, out int xray_id, out List list_celementchemistryclr)
{
Search_xray = new uint[2000];
Analysis_xray = new uint[2000];
xray_id = 0;
list_celementchemistryclr = new List();
//防止为空校验判断
if (resultFile.List_OTSField == null)
return;
Particle particle = resultFile.List_OTSField.Find(x => x.FieldID == in_clr_fieldid).ParticleList.Find(x => x.ParticleId == in_clr_tagid);
var tmpPart = new ParticleData(resultFile.FilePath).GetParticleXrayDataByFidAndPid(Convert.ToString(particle.FieldId), Convert.ToString(particle.XrayId));
if (tmpPart != null)
{
particle.XRayData = tmpPart.XRayData;
if (particle.XrayId > -1)
{
for (int i = 0; i < 2000; i++)
{
Analysis_xray[i] = BitConverter.ToUInt32(particle.XRayData, i * 4);
}
Search_xray = Analysis_xray;
xray_id = particle.XrayId;
list_celementchemistryclr = particle.ElementList;
}
}
}
///
/// 传入所有的物理field坐标点,和单个物理field的宽高,返回所有field的左上角位置,和整个field组成的rect大小
///
///
///
///
///
public Rectangle GetWlRectTopLeftAndRect(List in_list_point, int in_width, int in_height)
{
//分别获取整个rect的xy最小值和最大值
int i_rect_x_min = 100000000;
int i_rect_y_min = 100000000;
int i_rect_x_max = -100000000;
int i_rect_y_max = -100000000;
for (int i = 0; i < in_list_point.Count; i++)
{
if (i_rect_x_min > in_list_point[i].X)
i_rect_x_min = in_list_point[i].X;
if (i_rect_y_min > in_list_point[i].Y)
i_rect_y_min = in_list_point[i].Y;
if (i_rect_x_max < in_list_point[i].X)
i_rect_x_max = in_list_point[i].X;
if (i_rect_y_max < in_list_point[i].Y)
i_rect_y_max = in_list_point[i].Y;
}
Rectangle ret_rect = new Rectangle(i_rect_x_min, i_rect_y_min,
i_rect_x_max - i_rect_x_min, i_rect_y_max - i_rect_y_min);
return ret_rect;
}
///
/// 根据Field的ID,来获取Field列表中对应FIeld的OTS 坐标
///
///
///
public Point GetOTSPointByFieldID(List in_list_dfield, int in_fieldid)
{
Point ret_point = new Point(0, 0);
for (int i = 0; i < in_list_dfield.Count; i++)
{
//这里TagID先代表的是底层返回的ID
if (in_list_dfield[i].FieldID == in_fieldid.ToString())
{
ret_point = new Point(Convert.ToInt32(in_list_dfield[i].OTSCoordinatePos.X), Convert.ToInt32(in_list_dfield[i].OTSCoordinatePos.Y));
}
}
return ret_point;
}
///
/// 将OTS坐标转换为Sem 坐标
///
///
///
public Point ChangeOTSToSemCoord(Point POTSCoord)
{
//first if m_semstagedata is null to get stage inforation
Convert.ToDouble(((Dictionary)resultFile.ResultInfo["SEMStageData"])["scanFieldSize"]);
//after obtaining stage info,calc stage point data
Point ret_SEM_point = new Point();
// get center point, um
long xStart = Convert.ToInt64(((Dictionary)((Dictionary)((Dictionary)resultFile.ResultInfo["SEMStageData"])["Members"])["XAxis"])["start"]);
long xEnd = Convert.ToInt64(((Dictionary)((Dictionary)((Dictionary)resultFile.ResultInfo["SEMStageData"])["Members"])["XAxis"])["end"]);
long xCenter = (xStart + xEnd) / 2;
long yStart = Convert.ToInt64(((Dictionary)((Dictionary)((Dictionary)resultFile.ResultInfo["SEMStageData"])["Members"])["YAxis"])["start"]);
long yEnd = Convert.ToInt64(((Dictionary)((Dictionary)((Dictionary)resultFile.ResultInfo["SEMStageData"])["Members"])["YAxis"])["end"]);
long yCenter = (yStart + yEnd) / 2;
// delte = SEM - OTSa
long deltex = xCenter - 0;
long deltey = yCenter - 0;
int xdir = Convert.ToInt32(((Dictionary)resultFile.ResultInfo["SEMStageData"])["xAxisDir"]);
int ydir = Convert.ToInt32(((Dictionary)resultFile.ResultInfo["SEMStageData"])["yAxisDir"]);
if (xdir == (int)OTS_X_AXIS_DIRECTION.LEFT_TOWARD)
{
ret_SEM_point.X = -1 * (POTSCoord.X - Convert.ToInt32(deltex));
}
else if (xdir == (int)OTS_X_AXIS_DIRECTION.RIGHT_TOWARD)
{
ret_SEM_point.X = POTSCoord.X + Convert.ToInt32(deltex);
}
if (ydir == (int)OTS_Y_AXIS_DIRECTION.UP_TOWARD)
{
ret_SEM_point.Y = POTSCoord.Y + Convert.ToInt32(deltey);
}
else if (ydir == (int)OTS_Y_AXIS_DIRECTION.DOWN_TOWARD)
{
ret_SEM_point.Y = -1 * (POTSCoord.Y - Convert.ToInt32(deltey));
}
return ret_SEM_point;
}
#endregion
///
/// 判断该点是否在多边形的范围内
///
///
///
///
public bool WhetherInRange(DisplayParticle Part, Point WhetherPoint)
{
var rect = Part.GetShowRect();
if ((rect.Left < WhetherPoint.X && WhetherPoint.X < rect.Right) && (rect.Top < WhetherPoint.Y && WhetherPoint.Y < rect.Bottom))
{
var itm = Part;
PointF[] inPoints = itm.GetGPath().PathPoints;
bool b_inrange;
GraphicsPath myGraphicsPath = new GraphicsPath();
Region myRegion = new Region();
myGraphicsPath.Reset();
myGraphicsPath.AddPolygon(inPoints);
myRegion.MakeEmpty();
myRegion.Union(myGraphicsPath);
//返回判断点是否在多边形里
b_inrange = myRegion.IsVisible(WhetherPoint);
return b_inrange;
}
else
{
return false;
}
}
public bool WhetherInRange(RectangleF rec,PointF[] inPoints, Point WhetherPoint)
{
var rect = rec;
if ((rect.Left < WhetherPoint.X && WhetherPoint.X < rect.Right) && (rect.Top < WhetherPoint.Y && WhetherPoint.Y < rect.Bottom))
{
bool b_inrange;
GraphicsPath myGraphicsPath = new GraphicsPath();
Region myRegion = new Region();
myGraphicsPath.Reset();
myGraphicsPath.AddPolygon(inPoints);
myRegion.MakeEmpty();
myRegion.Union(myGraphicsPath);
//返回判断点是否在多边形里
b_inrange = myRegion.IsVisible(WhetherPoint);
return b_inrange;
}
else
{
return false;
}
}
///
/// 判断该点是否在多边形的范围内的float版本重载
///
///
///
///
public bool WhetherInRange(DisplayParticle Part,PointF WhetherPoint)
{
var rect = Part.GetShowRect();
if ((rect.Left < WhetherPoint.X && WhetherPoint.X < rect.Right) && (rect.Top < WhetherPoint.Y && WhetherPoint.Y < rect.Bottom))
{
var itm = Part;
PointF[] inPoints = itm.GetGPath().PathPoints;
bool b_inrange ;
GraphicsPath myGraphicsPath = new GraphicsPath();
Region myRegion = new Region();
myGraphicsPath.Reset();
myGraphicsPath.AddPolygon(inPoints);
myRegion.MakeEmpty();
myRegion.Union(myGraphicsPath);
//返回判断点是否在多边形里
b_inrange = myRegion.IsVisible(WhetherPoint);
return b_inrange;
}
else
{
return false;
}
}
#region 颗粒分割功能方法
///
/// 获取线段与矩形的两个交点
///
///
///
///
///
///
public bool GetInterBetweenLinesAndRect(Point line1S, Point line1E, RectangleF rectangle, ref List pointList)
{
try
{
PointF pointF = new PointF(-1, -1);
Rect rect = new Rect();
rect.X = m_ParticleSegmentation.ParticleData.RectLeft;
rect.Y = m_ParticleSegmentation.ParticleData.RectTop;
rect.Width = m_ParticleSegmentation.ParticleData.RectWidth;
rect.Height = m_ParticleSegmentation.ParticleData.RectHeight;
float border = 0;
if (GetInterBetweenTwoLines(line1S, line1E, new PointF(rectangle.Left, rectangle.Top), new PointF(rectangle.Right, rectangle.Top), ref pointF))
{
border = (pointF.X - rectangle.Left) / (rectangle.Right - rectangle.Left);
pointList.Add(new Point((int)(rect.X + rect.Width * border), rect.Y));
}
if (GetInterBetweenTwoLines(line1S, line1E,
new PointF(rectangle.Left, rectangle.Bottom), new PointF(rectangle.Right, rectangle.Bottom), ref pointF))
{
border = (pointF.X - rectangle.Left) / (rectangle.Right - rectangle.Left);
pointList.Add(new Point((int)(rect.X + rect.Width * border), rect.Y + rect.Height));
}
if (GetInterBetweenTwoLines(line1S, line1E,
new PointF(rectangle.Left, rectangle.Top), new PointF(rectangle.Left, rectangle.Bottom), ref pointF))
{
border = (pointF.Y - rectangle.Top) / (rectangle.Bottom - rectangle.Top);
pointList.Add(new Point(rect.X, (int)(rect.Y + rect.Height * border)));
}
if (GetInterBetweenTwoLines(line1S, line1E,
new PointF(rectangle.Right, rectangle.Top), new PointF(rectangle.Right, rectangle.Bottom), ref pointF))
{
border = (pointF.Y - rectangle.Top) / (rectangle.Bottom - rectangle.Top);
pointList.Add(new Point(rect.X + rect.Width, (int)(rect.Y + rect.Height * border)));
}
if (pointList.Count == 2)
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
log.Trace("(GetSplitPartFun)" + ex);
return false;
}
}
///
/// 获取分离颗粒方法
///
///
///
///
public bool GetSplitPartFun(Point startPoint, Point endPoint)
{
try
{
CImageHandler m_ImagePro = new CImageHandler();
Particle particle1 = (Particle)CloneObject(m_ParticleSegmentation.ParticleData);
Particle particle2 = (Particle)CloneObject(m_ParticleSegmentation.ParticleData);
Dictionary sampleMembers = ((Dictionary)((Dictionary)resultFile.ResultInfo["Sample"])["Members"]);
Dictionary imageScanParam = (Dictionary)((Dictionary)((Dictionary)sampleMembers["MsrParams"])["Members"])["ImageScanParam"];
double d_scanFieldSize_width = Convert.ToDouble(((Dictionary)resultFile.ResultInfo["SEMStageData"])["scanFieldSize"]);
string ImageResolution = imageScanParam["ImageResolution"].ToString();
int width = int.Parse(ImageResolution.Split('_')[1]);
int height = int.Parse(ImageResolution.Split('_')[2]);
double dPixelSize = d_scanFieldSize_width / width;
using (Mat mat = new Mat(height, width, MatType.CV_8UC1, Scalar.Black))//黑色底图
using (Mat labelMat = new Mat())
using (Mat stats = new Mat())
using (Mat centroids = new Mat())
using (Mat matBse = new Mat(resultFile.List_OTSField[particle1.FieldId].FieldImage, ImreadModes.Grayscale))
{
foreach (Segment segment in m_ParticleSegmentation.ParticleData.SegmentList)
{
Cv2.Line(mat, new OpenCvSharp.Point(segment.Start, segment.Height), new OpenCvSharp.Point(segment.Start + segment.Length, segment.Height), Scalar.White, 1, LineTypes.AntiAlias);
}
//寻找坐标点
List points1 = new List();
List points2 = new List();
List aveGray1 = new List();
List aveGray2 = new List();
for (int k = 0; k < mat.Height; k++)
{
for (int j = 0; j < mat.Width; j++)
{
if (mat.Get(k, j) != 0)
{
int side = (startPoint.X - j) * (endPoint.Y - k) - (startPoint.Y - k) * (endPoint.X - j);
if (side >= 0)//区分像素位置
{
points1.Add(new Point(j, k));
aveGray1.Add(matBse.Get(k, j));
}
else
{
points2.Add(new Point(j, k));
aveGray2.Add(matBse.Get(k, j));
}
}
}
}
//处理Segment
List SegmentClrList1 = new List();
List SegmentClrList2 = new List();
List SegmentList1 = new List();
List SegmentList2 = new List();
GetSegment(points1, SegmentClrList1, ref SegmentList1);
GetSegment(points2, SegmentClrList2, ref SegmentList2);
//颗粒一
Cv2.Threshold(mat, mat, 0, 0, ThresholdTypes.Binary);
foreach (Segment segment in SegmentList1)
{
Cv2.Line(mat, new OpenCvSharp.Point(segment.Start, segment.Height), new OpenCvSharp.Point(segment.Start + segment.Length, segment.Height), Scalar.White, 1, LineTypes.AntiAlias);
}
Cv2.ConnectedComponentsWithStats(mat, labelMat, stats, centroids, PixelConnectivity.Connectivity8);
CopyToPart(particle1, SegmentList1, SegmentClrList1, aveGray1, stats, centroids, dPixelSize);
//颗粒二
Cv2.Threshold(mat, mat, 0, 0, ThresholdTypes.Binary);
foreach (Segment segment in SegmentList2)
{
Cv2.Line(mat, new OpenCvSharp.Point(segment.Start, segment.Height), new OpenCvSharp.Point(segment.Start + segment.Length, segment.Height), Scalar.White, 1, LineTypes.AntiAlias);
}
Cv2.ConnectedComponentsWithStats(mat, labelMat, stats, centroids, PixelConnectivity.Connectivity8);
CopyToPart(particle2, SegmentList2, SegmentClrList2, aveGray2, stats, centroids, dPixelSize);
if (!SaveToDb(particle1, particle2))
{
log.Trace("(GetSplitPartFun) SaveToDb Faild");
return false;
}
}
return true;
}
catch (Exception ex)
{
log.Trace("(GetSplitPartFun)" + ex);
return false;
}
}
///
/// 拷贝颗粒数据
///
///
///
///
///
///
///
///
private void CopyToPart(Particle particle, List segments, List SegmentClrList, List aveGray, Mat stats, Mat centroids, double dPixelSize)
{
CImageHandler m_ImagePro = new CImageHandler();
COTSParticleClr part = new COTSParticleClr();
part.SetActualArea(stats.At(1, 4) * dPixelSize * dPixelSize);
part.SetParticleRect(new Rectangle(stats.At(1, 0), stats.At(1, 1), stats.At(1, 2), stats.At(1, 3)));
part.GetFeature().SetSegmentsList(SegmentClrList, false);
m_ImagePro.CalParticleImageProp(part, dPixelSize);
particle.SegmentList = segments;
particle.SegmentNum = segments.Count;
particle.AveGray = (int)aveGray.Average();
particle.RectLeft = stats.At(1, 0);
particle.RectTop = stats.At(1, 1);
particle.RectWidth = stats.At(1, 2);
particle.RectHeight = stats.At(1, 3);
particle.Area = stats.At(1, 4) * dPixelSize * dPixelSize;
particle.PosX = (int)centroids.At(1, 0);
particle.PosY = (int)centroids.At(1, 1);
particle.DFERET = part.GetFeretDiameter();
particle.DMAX = part.GetDMAX();
particle.DMIN = part.GetDMIN();
particle.DPERP = part.GetDMPERP();
particle.PERIMETER = part.GetDPRIMETER();
particle.ORIENTATION = part.GetORIENTATION();
particle.DINSCR = part.GetDINSCR();
particle.DMEAN = part.GetDMEAN();
particle.DELONG = part.GetDELONG();
}
///
/// 保存数据库
///
///
///
///
public bool SaveToDb(Particle particle1, Particle particle2)
{
//初始化
SQLiteHelper sQLiteHelper = new SQLiteHelper(resultFile.FilePath + "\\FIELD_FILES\\Inclusion.db");
sQLiteHelper.GetDBConnection();
sQLiteHelper.BeginTransaction();
//修改Segment表
if (particle1.SegmentList.Count == 0 || particle2.SegmentList.Count == 0)
{
return false;
}
int SegmentCount = sQLiteHelper.ExecuteNewPartIdForTransaction() + 1;
if (!sQLiteHelper.ExecuteSegmentForTransaction(particle1, particle2, SegmentCount))//修改Segment表
{
return false;
}
if (!sQLiteHelper.ExecuteXrayForTransaction(particle1, particle2, SegmentCount))//修改XRayData和PoxXrayInfo表
{
return false;
}
if (!sQLiteHelper.ExecuteIncAForTransaction(particle1, particle2, SegmentCount))//修改IncAData表
{
return false;
}
sQLiteHelper.CommitTransaction();
return true;
}
///
/// 线段与矩形是否相交
///
///
///
///
///
///
///
///
///
///
public bool isLineIntersectRectangle(float linePointX1,
float linePointY1,
float linePointX2,
float linePointY2,
float rectangleLeftTopX,
float rectangleLeftTopY,
float rectangleRightBottomX,
float rectangleRightBottomY)
{
float lineHeight = linePointY1 - linePointY2;
float lineWidth = linePointX2 - linePointX1; // 计算叉乘
float c = linePointX1 * linePointY2 - linePointX2 * linePointY1;
if ((lineHeight * rectangleLeftTopX + lineWidth * rectangleLeftTopY + c >= 0 && lineHeight * rectangleRightBottomX + lineWidth * rectangleRightBottomY + c <= 0)
|| (lineHeight * rectangleLeftTopX + lineWidth * rectangleLeftTopY + c <= 0 && lineHeight * rectangleRightBottomX + lineWidth * rectangleRightBottomY + c >= 0)
|| (lineHeight * rectangleLeftTopX + lineWidth * rectangleRightBottomY + c >= 0 && lineHeight * rectangleRightBottomX + lineWidth * rectangleLeftTopY + c <= 0)
|| (lineHeight * rectangleLeftTopX + lineWidth * rectangleRightBottomY + c <= 0 && lineHeight * rectangleRightBottomX + lineWidth * rectangleLeftTopY + c >= 0))
{
if (rectangleLeftTopX > rectangleRightBottomX)
{
float temp = rectangleLeftTopX;
rectangleLeftTopX = rectangleRightBottomX;
rectangleRightBottomX = temp;
}
if (rectangleLeftTopY < rectangleRightBottomY)
{
float temp1 = rectangleLeftTopY;
rectangleLeftTopY = rectangleRightBottomY;
rectangleRightBottomY = temp1;
}
if ((linePointX1 < rectangleLeftTopX && linePointX2 < rectangleLeftTopX)
|| (linePointX1 > rectangleRightBottomX && linePointX2 > rectangleRightBottomX)
|| (linePointY1 > rectangleLeftTopY && linePointY2 > rectangleLeftTopY)
|| (linePointY1 < rectangleRightBottomY && linePointY2 < rectangleRightBottomY))
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}
///
/// 求一个线段与另一个线段的交点
///
///
///
///
///
///
/// -1:不存在交点;1:存在一个交点;2:存在无穷多个交点(重合或部分重合)
public bool GetInterBetweenTwoLines(PointF line1S, PointF line1E,
PointF line2S, PointF line2E, ref PointF interPoint)
{
int status = -1;
// 判断两条直线各自的矩形包围盒的X与Y的值范围
float line1Xmin = line1S.X < line1E.X ? line1S.X : line1E.X,
line1Xmax = line1S.X > line1E.X ? line1S.X : line1E.X,
line1Ymin = line1S.Y < line1E.Y ? line1S.Y : line1E.Y,
line1Ymax = line1S.Y > line1E.Y ? line1S.Y : line1E.Y,
line2Xmin = line2S.X < line2E.X ? line2S.X : line2E.X,
line2Xmax = line2S.X > line2E.X ? line2S.X : line2E.X,
line2Ymin = line2S.Y < line2E.Y ? line2S.Y : line2E.Y,
line2Ymax = line2S.Y > line2E.Y ? line2S.Y : line2E.Y;
if (line1S.X - line1E.X == 0)
{
// 两条线都垂直于X轴
if (line2S.X - line2E.X == 0)
{
if (line1S.X != line2S.X) status = -1;
else if ((line1Ymin > line2Ymax) || (line1Ymax < line2Ymin)) status = -1;
else if (line1Ymin == line2Ymax)
{
interPoint = new PointF(line1S.X, line1Ymin); status = 1;
}
else if (line1Ymax == line2Ymin)
{
interPoint = new PointF(line1S.X, line1Ymax); status = 1;
}
else status = 2;
}
// line1垂直于X轴,line2不垂直于X轴
else
{
float slope = (line2S.Y - line2E.Y) / (line2S.X - line2E.X);
float offset = line2S.Y - slope * line2S.X;
float newX = line1S.X, newY = slope * newX + offset;
if (newX >= line2Xmin && newX <= line2Xmax && newY >= line1Ymin && newY <= line1Ymax
&& newY >= line2Ymin && newY <= line2Ymax)
{
interPoint = new PointF(newX, newY); status = 1;
}
}
}
else
{
// line1不垂直于X轴,line2垂直于X轴
if (line2S.X - line2E.X == 0)
{
float slope = (line1S.Y - line1E.Y) / (line1S.X - line1E.X);
float offset = line1S.Y - slope * line1S.X;
float newX = line2S.X, newY = slope * newX + offset;
if (newX >= line1Xmin && newX <= line1Xmax && newY >= line1Ymin && newY <= line1Ymax
&& newY >= line2Ymin && newY <= line2Ymax)
{
interPoint = new PointF(newX, newY); status = 1;
}
}
// line1和line2都不垂直于X轴
else
{
float slope1 = (line1S.Y - line1E.Y) / (line1S.X - line1E.X);
float offset1 = line1S.Y - slope1 * line1S.X;
float slope2 = (line2S.Y - line2E.Y) / (line2S.X - line2E.X);
float offset2 = line2S.Y - slope2 * line2S.X;
// 如果两条直线平行
if (slope1 == slope2)
{
if (offset1 != offset2) status = -1;
else if (line1Xmax == line2Xmin)
{
interPoint = new PointF(line1Xmax, line1Xmax * slope1 + offset1); status = 1;
}
else if (line1Xmin == line2Xmax)
{
interPoint = new PointF(line1Xmin, line1Xmin * slope1 + offset1); status = 1;
}
else if (line1Xmax < line2Xmin || line1Xmin > line2Xmax) status = -1;
else status = 2;
}
else
{
float newX = (offset2 - offset1) / (slope1 - slope2), newY = newX * slope1 + offset1;
if (newX >= line1Xmin && newX <= line1Xmax && newX >= line2Xmin && newX <= line2Xmax)
{
interPoint = new PointF(newX, newY); status = 1;
}
}
}
}
if (status == 1)
{
return true;
}
else
{
return false;
}
}
///
/// 获取Segment信息
///
///
///
///
public void GetSegment(List points, List SegmentClrList, ref List SegmentList)
{
List segmentStart = new List();
List segmentHeight = new List();
List segmentLength = new List();
FindSegment(points, ref segmentStart, ref segmentHeight, ref segmentLength);
for (int i = 0; i < segmentLength.Count; i++)
{
COTSSegmentClr seg = new COTSSegmentClr();
seg.SetStart(segmentStart[i]);
seg.SetHeight(segmentHeight[i]);
seg.SetLength(segmentLength[i]);
SegmentClrList.Add(seg);
Segment segment = new Segment();
segment.Start = segmentStart[i];
segment.Height = segmentHeight[i];
segment.Length = segmentLength[i];
segment.SegmentNum = segmentLength.Count;
segment.SegmentId = i;
segment.FieldId = m_ParticleSegmentation.ParticleData.FieldId;
segment.XRayId = m_ParticleSegmentation.ParticleData.XrayId;
segment.ParticleId = m_ParticleSegmentation.ParticleData.ParticleId;
SegmentList.Add(segment);
}
}
///
/// 寻找segment方法
///
public void FindSegment(List point_list_final, ref List segmentStart, ref List segmentHeight, ref List segmentLength)
{
int flag = 0;
point_list_final.Sort(my_sort);//排序
for (int k = 0; k < point_list_final.Count(); k++)
{
if (k == 0 && k != point_list_final.Count() - 1)//第一个颗粒
{
flag++;
segmentStart.Add(point_list_final[k].X);
segmentHeight.Add(point_list_final[k].Y);
}
else if (k == 0 && k == point_list_final.Count() - 1)//只有一个颗粒
{
segmentStart.Add(point_list_final[k].X);
segmentHeight.Add(point_list_final[k].Y);
segmentLength.Add(1);
}
else if (k == point_list_final.Count() - 1)//最后一个颗粒
{
flag++;
segmentLength.Add(flag);
}
else if (point_list_final[k].Y == point_list_final[k - 1].Y && point_list_final[k].X == point_list_final[k - 1].X + 1)//同行连续
{
flag++;
}
else if (point_list_final[k].Y == point_list_final[k - 1].Y && point_list_final[k].X != point_list_final[k - 1].X + 1)//同行隔断
{
segmentLength.Add(flag);
flag = 1;
segmentStart.Add(point_list_final[k].X);
segmentHeight.Add(point_list_final[k].Y);
}
else if (point_list_final[k].Y != point_list_final[k - 1].Y)//不同行
{
segmentLength.Add(flag);
flag = 1;
segmentStart.Add(point_list_final[k].X);
segmentHeight.Add(point_list_final[k].Y);
}
}
}
///
/// 排序方法
///
///
///
///
private int my_sort(Point p1, Point p2)
{
return p1.Y == p2.Y ? p1.X.CompareTo(p2.X) : p1.Y.CompareTo(p2.Y); //升序排序
}
public object CloneObject(object obj)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
stream.Position = 0;
formatter.Serialize(stream, obj);
stream.Position = 0;
return formatter.Deserialize(stream);
}
}
#endregion
}
}