952 lines
35 KiB
C#
952 lines
35 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Management;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Windows.Forms;
|
|
using System.Xml;
|
|
|
|
namespace CoreUnit.Common
|
|
{
|
|
public class UtilUnit
|
|
{
|
|
|
|
public enum IOType { DI, DO, AI, AO };
|
|
|
|
public enum ReactiveLayerStateType //ReactiveLayer 상태
|
|
{
|
|
IDLE, //초기화 전
|
|
READY, //초기화 후
|
|
RUN,
|
|
PAUSE,//일시 정지
|
|
HEAVYALARM, //Heavy Alarm
|
|
LIGHTALARM
|
|
};
|
|
public enum ReactiveLayerOperationType //ReactiveLayer 운전 모드
|
|
{
|
|
None,
|
|
Manual,
|
|
SemiAuto,
|
|
DryRun,
|
|
Auto
|
|
};
|
|
public static LogUnit logUnit = new LogUnit();
|
|
|
|
public static Dictionary<string, UtilUnit.ControlLanguage> ControlLanguages = new Dictionary<string, UtilUnit.ControlLanguage>();
|
|
public enum eLanguage { Korean, English };
|
|
|
|
public enum eMachineName { Other, H52A_ACW, H52A_CCW, CIT}
|
|
|
|
public class ControlLanguage
|
|
{
|
|
public string controlName = "";
|
|
public string koreanName = "";
|
|
public string englishName = "";
|
|
|
|
public ControlLanguage(string control, string korean, string english)
|
|
{
|
|
controlName = control;
|
|
koreanName = korean;
|
|
englishName = english;
|
|
}
|
|
|
|
}
|
|
public static List<System.Windows.Forms.Control> GetAllControls(System.Windows.Forms.Control control)
|
|
{
|
|
List<System.Windows.Forms.Control> controlList = new List<System.Windows.Forms.Control>();
|
|
|
|
foreach (System.Windows.Forms.Control ctrl in control.Controls) {
|
|
controlList.Add(ctrl);
|
|
|
|
if (ctrl.Controls.Count > 0) {
|
|
controlList.AddRange(GetAllControls(ctrl));
|
|
|
|
}
|
|
}
|
|
|
|
return controlList;
|
|
|
|
}
|
|
|
|
public static List<ToolStripItem> GetAllToolStripItems(ToolStrip toolStrip)
|
|
{
|
|
List<ToolStripItem> toolStripItems = new List<ToolStripItem>();
|
|
|
|
foreach (ToolStripItem item in toolStrip.Items) {
|
|
toolStripItems.Add(item);
|
|
|
|
if (item is ToolStripMenuItem) {
|
|
toolStripItems.AddRange(GetAllToolStripMenuItems((ToolStripMenuItem)item));
|
|
}
|
|
}
|
|
|
|
|
|
return toolStripItems;
|
|
|
|
}
|
|
|
|
public static List<ToolStripMenuItem> GetAllToolStripMenuItems(ToolStripMenuItem toolStripMenuItem)
|
|
{
|
|
List<ToolStripMenuItem> toolStripMenuItems = new List<ToolStripMenuItem>();
|
|
|
|
foreach (ToolStripMenuItem item in toolStripMenuItem.DropDownItems) {
|
|
|
|
toolStripMenuItems.Add(item);
|
|
|
|
if (item.DropDownItems.Count > 0) {
|
|
toolStripMenuItems.AddRange(GetAllToolStripMenuItems(item));
|
|
}
|
|
|
|
}
|
|
|
|
return toolStripMenuItems;
|
|
|
|
}
|
|
#region Registry
|
|
public static string GetRegistryValue(string keyName, string valueName, string defaultValue)
|
|
{
|
|
object value = Microsoft.Win32.Registry.GetValue(keyName, valueName, defaultValue);
|
|
if (value == null) {
|
|
return defaultValue;
|
|
}
|
|
return value.ToString();
|
|
}
|
|
|
|
public static double GetRegistryValue(string keyName, string valueName, double defaultValue)
|
|
{
|
|
string str = GetRegistryValue(keyName, valueName, defaultValue.ToString());
|
|
double value = 0;
|
|
if (false == double.TryParse(str, out value)) {
|
|
return defaultValue;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
public static int GetRegistryValue(string keyName, string valueName, int defaultValue)
|
|
{
|
|
string str = GetRegistryValue(keyName, valueName, defaultValue.ToString());
|
|
int value = 0;
|
|
if (false == int.TryParse(str, out value)) {
|
|
return defaultValue;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
public static void SetRegistryValue(string keyName, string valueName, string value)
|
|
{
|
|
string defaultValue = "";
|
|
string temp = GetRegistryValue(keyName, valueName, defaultValue);
|
|
if (temp != value) {
|
|
Microsoft.Win32.Registry.SetValue(keyName, valueName, value);
|
|
UtilUnit.logUnit.SetLog(LogUnit.eLogType.SYSTEM, System.Reflection.MethodBase.GetCurrentMethod().Name, string.Format("Registry Changed [keyName : {0}], [valueName : {1}], [value : {2} → {3}]", keyName, valueName, temp, value));
|
|
}
|
|
}
|
|
|
|
public static void SetRegistryValue(string keyName, string valueName, double value)
|
|
{
|
|
double defaultValue = -1;
|
|
double temp = GetRegistryValue(keyName, valueName, defaultValue);
|
|
if (temp != value) {
|
|
Microsoft.Win32.Registry.SetValue(keyName, valueName, value);
|
|
UtilUnit.logUnit.SetLog(LogUnit.eLogType.SYSTEM, System.Reflection.MethodBase.GetCurrentMethod().Name, string.Format("Registry Changed [keyName : {0}], [valueName : {1}], [value : {2} → {3}]", keyName, valueName, temp, value));
|
|
}
|
|
}
|
|
|
|
public static void SetRegistryValue(string keyName, string valueName, int value)
|
|
{
|
|
int defaultValue = -1;
|
|
int temp = GetRegistryValue(keyName, valueName, defaultValue);
|
|
if (temp != value) {
|
|
Microsoft.Win32.Registry.SetValue(keyName, valueName, value);
|
|
UtilUnit.logUnit.SetLog(LogUnit.eLogType.SYSTEM, System.Reflection.MethodBase.GetCurrentMethod().Name, string.Format("Registry Changed [keyName : {0}], [valueName : {1}], [value : {2} → {3}]", keyName, valueName, temp, value));
|
|
}
|
|
}
|
|
#endregion Registry
|
|
|
|
#region Data 처리
|
|
public static string ConvertShortArrayToString(short[] array)
|
|
{
|
|
System.Text.StringBuilder buf = new System.Text.StringBuilder();
|
|
int maxIndex = array.Length - 1;
|
|
for (int i = 0; i <= maxIndex; i++) {
|
|
buf.Append(array[i]);
|
|
}
|
|
return buf.ToString();
|
|
}
|
|
|
|
public static List<double> ShiftData(List<double> data, double shift)
|
|
{
|
|
List<double> shiftData = new List<double>();
|
|
foreach (double val in data) {
|
|
|
|
shiftData.Add(val - shift);
|
|
|
|
}
|
|
return shiftData;
|
|
}
|
|
|
|
public static byte[] ConvertHexStringToByteArray(string hexString)
|
|
{
|
|
if (hexString.Length % 2 != 0) {
|
|
throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
|
|
}
|
|
|
|
byte[] HexAsBytes = new byte[hexString.Length / 2];
|
|
for (int index = 0; index < HexAsBytes.Length; index++) {
|
|
string byteValue = hexString.Substring(index * 2, 2);
|
|
HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
Array.Reverse(HexAsBytes);
|
|
|
|
return HexAsBytes;
|
|
}
|
|
|
|
public static double DegreeToRadian(double angle)
|
|
{
|
|
return Math.PI * angle / 180.0;
|
|
}
|
|
|
|
public static double RadianToDegree(double radian)
|
|
{
|
|
return radian * (180.0 / Math.PI);
|
|
}
|
|
|
|
public static List<bool> ConvertDecimalToBinary(int vlaue)
|
|
{
|
|
int binary;
|
|
char[] binaryHolder = new char[1];
|
|
string binaryResult = "";
|
|
while (vlaue > 0) {
|
|
binary = vlaue % 2;
|
|
binaryResult += binary;
|
|
vlaue = vlaue / 2;
|
|
}
|
|
|
|
binaryHolder = binaryResult.ToCharArray();
|
|
Array.Reverse(binaryHolder);
|
|
binaryResult = new string(binaryHolder);
|
|
|
|
List<bool> binaryList = new List<bool>();
|
|
return binaryList;
|
|
}
|
|
public static int CutValue(int value, int min, int max)
|
|
{
|
|
if (value > max) {
|
|
return max;
|
|
} else if (value < min) {
|
|
return min;
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
|
|
public static string ConvertStringStreamFromList(List<double> posList)
|
|
{
|
|
string currPos = "";
|
|
|
|
for (int i = 0; i < posList.Count; i++) {
|
|
currPos += string.Format("{0:F5},", posList[i]);
|
|
}
|
|
|
|
currPos = currPos.Remove(currPos.LastIndexOf(','));
|
|
|
|
return currPos;
|
|
}
|
|
public static string ConvertStringStreamFromDateTimeList(List<int> dateTimeList)
|
|
{
|
|
string currPos = "";
|
|
|
|
for (int i = 0; i < dateTimeList.Count; i++) {
|
|
currPos += dateTimeList[i] + ",";
|
|
}
|
|
|
|
currPos = currPos.Remove(currPos.LastIndexOf(','));
|
|
|
|
return currPos;
|
|
}
|
|
|
|
public static List<double> ConvertListFromStringStream(string posStream)
|
|
{
|
|
List<double> posList = new List<double>();
|
|
string[] token = posStream.Split(',');
|
|
for (int tokenIndex = 0; tokenIndex < token.Length; tokenIndex++) {
|
|
posList.Add(Convert.ToDouble(token[tokenIndex]));
|
|
}
|
|
|
|
return posList;
|
|
}
|
|
|
|
public static List<string> ConvertAxisIDListFromAxisIDStream(string axisIDStream)
|
|
{
|
|
List<string> axisIDList = new List<string>();
|
|
string[] token = axisIDStream.Split(',');
|
|
for (int tokenIndex = 0; tokenIndex < token.Length; tokenIndex++) {
|
|
axisIDList.Add(token[tokenIndex]);
|
|
}
|
|
|
|
return axisIDList;
|
|
}
|
|
public static Color ConvertColorFromStringStream(string str)
|
|
{
|
|
string[] spstring = str.Split(',');
|
|
|
|
if (spstring.Length == 1)
|
|
return Enum.TryParse(str, true, out KnownColor color)
|
|
? Color.FromKnownColor(color)
|
|
: Color.White;
|
|
|
|
int[] iNumber = spstring
|
|
.Select(s => int.Parse(Regex.Replace(s, @"\D", "")))
|
|
.ToArray();
|
|
|
|
if (spstring.Length == 4) // ARGB
|
|
return Color.FromArgb(iNumber[0], iNumber[1], iNumber[2], iNumber[3]);
|
|
|
|
if (spstring.Length == 3) // RGB
|
|
return Color.FromArgb(0xFF, iNumber[0], iNumber[1], iNumber[2]);
|
|
|
|
return Color.White;
|
|
}
|
|
public static List<double> Threshold(List<double> data, double thresholdMin, double thresholdMax)
|
|
{
|
|
List<double> thresholdData = new List<double>();
|
|
foreach (double val in data) {
|
|
if (thresholdMin <= val && val <= thresholdMax) {
|
|
thresholdData.Add(val);
|
|
}
|
|
}
|
|
return thresholdData;
|
|
}
|
|
|
|
public static List<double> Median1D(List<double> data, int filterLength)
|
|
{
|
|
int middleNo = filterLength % 2 + 1;
|
|
List<double> filteredData = new List<double>();
|
|
for (int iNo = 0; iNo <= data.Count - filterLength; iNo++) {
|
|
List<double> temp = data.GetRange(iNo, filterLength);
|
|
temp.Sort();
|
|
filteredData.Add(temp[middleNo]);
|
|
}
|
|
return filteredData;
|
|
}
|
|
|
|
public static List<double> MovingAverage(List<double> data, int filterLength)
|
|
{
|
|
List<double> filteredData = new List<double>();
|
|
for (int iNo = 0; iNo <= data.Count - filterLength; iNo++) {
|
|
filteredData.Add(data.GetRange(iNo, filterLength - 1).Average());
|
|
}
|
|
return filteredData;
|
|
}
|
|
|
|
public static List<double> Minimum(List<double> data, int filterLength)
|
|
{
|
|
List<double> filteredData = new List<double>();
|
|
for (int iNo = 0; iNo <= data.Count - filterLength; iNo++) {
|
|
filteredData.Add(Minimum(data.GetRange(iNo, filterLength - 1)));
|
|
}
|
|
return filteredData;
|
|
}
|
|
|
|
public static double Minimum(List<double> data)
|
|
{
|
|
double temp = 9999.99;
|
|
for (int i = 0; i < data.Count; i++) {
|
|
temp = Math.Min(data[i], temp);
|
|
}
|
|
return temp;
|
|
}
|
|
|
|
public static List<double> Maximum(List<double> data, int filterLength)
|
|
{
|
|
List<double> filteredData = new List<double>();
|
|
for (int iNo = 0; iNo <= data.Count - filterLength; iNo++) {
|
|
filteredData.Add(Maximum(data.GetRange(iNo, filterLength - 1)));
|
|
}
|
|
return filteredData;
|
|
}
|
|
|
|
public static double Maximum(List<double> data)
|
|
{
|
|
double temp = -9999.99;
|
|
for (int i = 0; i < data.Count; i++) {
|
|
temp = Math.Max(data[i], temp);
|
|
}
|
|
return temp;
|
|
}
|
|
|
|
public static List<double> Derivative(List<double> data, int interbal)
|
|
{
|
|
List<double> derivativeData = new List<double>();
|
|
for (int i = 0; i < data.Count - interbal; i++) {
|
|
double value = (data[i + interbal] - data[i]) / interbal;
|
|
derivativeData.Add(value);
|
|
}
|
|
return derivativeData;
|
|
}
|
|
#endregion Data 처리
|
|
|
|
#region 파일 관리 기능
|
|
public static string GetFileExtension(string filePath)
|
|
{
|
|
return Path.GetExtension(filePath);
|
|
}
|
|
public static string GetFileName(string filePath)
|
|
{
|
|
return Path.GetFileName(filePath);
|
|
}
|
|
public static string GetFileNameWithoutExtension(string filePath)
|
|
{
|
|
return Path.GetFileNameWithoutExtension(filePath);
|
|
}
|
|
public static string GetDirectoryName(string filePath)
|
|
{
|
|
return Path.GetDirectoryName(filePath);
|
|
}
|
|
public static string CombineFileName(string path1, string path2)//경로의 구분자인 역슬레쉬를 안 넣어줘도 됨
|
|
{
|
|
return Path.Combine(path1, path2);
|
|
}
|
|
#endregion
|
|
|
|
#region INI 파일 읽기 및 쓰기
|
|
[DllImport("kernel32.dll")]
|
|
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
|
|
|
|
// INI 값을 읽어 온다.
|
|
public static void GetIniValue(string fileName, string section, string key, ref string value)
|
|
{
|
|
StringBuilder temp = new StringBuilder(255);
|
|
int i = GetPrivateProfileString(section, key, "", temp, 255, fileName);
|
|
value = temp.ToString();
|
|
}
|
|
|
|
public static void GetIniValue(string fileName, string section, string key, ref int value)
|
|
{
|
|
string temp = string.Empty;
|
|
GetIniValue(fileName, section, key, ref temp);
|
|
value = Convert.ToInt32(temp);
|
|
}
|
|
|
|
public static void GetIniValue(string fileName, string section, string key, ref double value)
|
|
{
|
|
string temp = string.Empty;
|
|
GetIniValue(fileName, section, key, ref temp);
|
|
value = Convert.ToDouble(temp);
|
|
}
|
|
|
|
public static void GetIniValue(string fileName, string section, string key, ref uint value)
|
|
{
|
|
string temp = string.Empty;
|
|
GetIniValue(fileName, section, key, ref temp);
|
|
value = Convert.ToUInt32(temp);
|
|
}
|
|
|
|
// INI 값을 셋팅
|
|
public static void SetIniValue(string fileName, string section, string Key, string value)
|
|
{
|
|
WritePrivateProfileString(section, Key, value, fileName);
|
|
}
|
|
|
|
public static void SetIniValue(string fileName, string section, string Key, int value)
|
|
{
|
|
WritePrivateProfileString(section, Key, value.ToString(), fileName);
|
|
}
|
|
|
|
public static void SetIniValue(string fileName, string section, string Key, double value)
|
|
{
|
|
WritePrivateProfileString(section, Key, value.ToString(), fileName);
|
|
}
|
|
#endregion
|
|
|
|
#region 좌표 변환(translation) 기능
|
|
public static void TranslateCoordination(PointF originalPt, ref PointF translatedPt, float angle = 0, PointF center = new PointF())//Angle는 degree
|
|
{
|
|
float rad = (float)(angle * Math.PI / 180);
|
|
translatedPt.X = (float)((originalPt.X - center.X) * Math.Cos(rad) - (originalPt.Y - center.Y) * Math.Sin(rad) + center.X);
|
|
translatedPt.Y = (float)((originalPt.X - center.X) * Math.Sin(rad) + (originalPt.Y - center.Y) * Math.Cos(rad) + center.Y);
|
|
}
|
|
#endregion
|
|
|
|
#region 비트 연산
|
|
public static byte[] BitArrayToByteArray(BitArray bits)
|
|
{
|
|
byte[] ret = new byte[(bits.Length - 1) / 8 + 1];
|
|
bits.CopyTo(ret, 0);
|
|
return ret;
|
|
}
|
|
#endregion
|
|
|
|
#region 5.시스템 메모리 확인 기능
|
|
enum MemorySizeType { Byte, KB, MB, GB, TB }
|
|
static ManagementClass cls = new ManagementClass("Win32_OperatingSystem");
|
|
static int ctrlTitleDisplayCount = 0;
|
|
static int writeFileCount = 0;
|
|
static string strMemorySize = "";
|
|
public static string GetCurrentProcessMemorySize()
|
|
{
|
|
long usageMemory = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
|
|
|
|
string retStr = string.Empty;
|
|
StringBuilder sb = new System.Text.StringBuilder();
|
|
|
|
int i = 0;
|
|
while (usageMemory > 1024L) { usageMemory = (Int64)(usageMemory / 1024L); i++; }
|
|
MemorySizeType sizeType = (MemorySizeType)i;
|
|
sb.AppendFormat("Process Memory: {0} {1}", usageMemory, sizeType.ToString()); retStr = sb.ToString();
|
|
return sb.ToString();
|
|
}
|
|
public static string GetCurrentFreePhysicalMemorySize()
|
|
{
|
|
int memorySize = 0;
|
|
|
|
ManagementObjectCollection instances = cls.GetInstances();
|
|
|
|
foreach (ManagementObject instance in instances) {
|
|
memorySize = int.Parse(instance["FreePhysicalMemory"].ToString());
|
|
}
|
|
|
|
return string.Format("Free Physical Memory: {0:#,###} MB", memorySize / 1024);
|
|
}
|
|
public static void UpdateSystemMemory(int periodTime/*단위는 ms*/, System.Windows.Forms.Control ctrl, string title, bool isWriteToFile)
|
|
{
|
|
if (periodTime * ctrlTitleDisplayCount > 100000) //updateTime 초 이상 지나면 control title 업데이트
|
|
{
|
|
ctrlTitleDisplayCount = 0;
|
|
strMemorySize = string.Format("{0} ({1}, {2})", title, GetCurrentProcessMemorySize(), GetCurrentFreePhysicalMemorySize());
|
|
} else {
|
|
ctrlTitleDisplayCount++;
|
|
}
|
|
|
|
if ((isWriteToFile) && (periodTime * writeFileCount > 3600000)) //1시간 지나면 저장함.
|
|
{
|
|
writeFileCount = 0;
|
|
UtilUnit.logUnit.SetLog(LogUnit.eLogType.SYSTEM, MethodBase.GetCurrentMethod().Name, strMemorySize, LogUnit.eLogLevel.LOW);
|
|
} else {
|
|
writeFileCount++;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 6.현재 코드 위치, 함수 이름 가져오기
|
|
public static string GetCurrentStackFrameInfo()
|
|
{
|
|
StackTrace st = new StackTrace(true);
|
|
StackFrame sf = st.GetFrame(1);
|
|
MethodBase m = sf.GetMethod();
|
|
|
|
return string.Format("{0}({1}), {2}.{3}", sf.GetFileName(), sf.GetFileLineNumber(), m.ReflectedType.FullName, m.Name);
|
|
}
|
|
|
|
public static string GetCurrentMethodFullName()
|
|
{
|
|
StackTrace st = new StackTrace(true);
|
|
StackFrame sf = st.GetFrame(1);
|
|
MethodBase m = sf.GetMethod();
|
|
|
|
return string.Format("{0}.{1}", m.ReflectedType.FullName, m.Name);
|
|
}
|
|
#endregion
|
|
|
|
#region 기하 계산 함수 모음
|
|
/// <summary>
|
|
/// 두 점을 잇는 직선의 기울기를 구하는 함수
|
|
/// </summary>
|
|
/// <param name="lp1">첫번째 점</param>
|
|
/// <param name="lp2">두번째 점</param>
|
|
/// <returns>두 점을 잇는 직선의 기술기. 단위는 Radian</returns>
|
|
public static double LineAngle(Point lp1, Point lp2)
|
|
{
|
|
if (lp1.X == lp2.X) {
|
|
if (lp1.Y > lp2.Y)
|
|
return Math.PI * 6 / 4;
|
|
if (lp1.Y < lp2.Y)
|
|
return Math.PI / 2;
|
|
return 0;
|
|
}
|
|
// first find angle A
|
|
double adjacent = lp2.X - lp1.X;
|
|
double opposite = lp2.Y - lp1.Y;
|
|
// find angle A
|
|
double A = Math.Atan(opposite / adjacent);
|
|
if (adjacent < 0) // 2nd and 3rd quadrant
|
|
A += Math.PI; // + 180
|
|
if (adjacent > 0 && opposite < 0) // 4th quadrant
|
|
A += Math.PI * 2; // +360
|
|
return A;
|
|
}
|
|
|
|
public static double LineAngleDegree(Point lp1, Point lp2)
|
|
{
|
|
double radian = LineAngle(lp1, lp2);
|
|
|
|
return radian * 180 / Math.PI;
|
|
}
|
|
public static double LineDistance(PointF p1, PointF p2, bool abs = true)
|
|
{
|
|
double dx = p1.X - p2.X;
|
|
double dy = p1.Y - p2.Y;
|
|
if (abs) {
|
|
dx = Math.Abs(dx);
|
|
dy = Math.Abs(dy);
|
|
}
|
|
if (dx == 0)
|
|
return dy;
|
|
if (dy == 0)
|
|
return dx;
|
|
return Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
|
|
}
|
|
|
|
public static List<PointF> LineDividePoint(PointF startPoint, PointF endPoint, int divideCount)
|
|
{
|
|
List<PointF> dividedPoint = new List<PointF>();
|
|
|
|
if (divideCount != 0) {
|
|
//등분 거리
|
|
double dx = (endPoint.X - startPoint.X) / divideCount;
|
|
double dy = (endPoint.Y - startPoint.Y) / divideCount;
|
|
|
|
for (int i = 0; i < divideCount; i++) {
|
|
double pointX = dx * i + startPoint.X;
|
|
double pointY = dy * i + startPoint.Y;
|
|
|
|
dividedPoint.Add(new PointF((float)pointX, (float)pointY));
|
|
}
|
|
} else {
|
|
dividedPoint.Add(startPoint);
|
|
}
|
|
|
|
|
|
|
|
return dividedPoint;
|
|
}
|
|
#region Linear Regression
|
|
public static void LinearRegression(List<PointF> point, out double yIntercept, out double slope)
|
|
{
|
|
//참고 링크 : https://en.wikipedia.org/wiki/Simple_linear_regression#Numerical_example
|
|
|
|
double sumOfX = 0;
|
|
double sumOfY = 0;
|
|
double sumOfXSq = 0;
|
|
double sumOfYSq = 0;
|
|
double sumCodeviates = 0;
|
|
|
|
for (int i = 0; i < point.Count; i++) {
|
|
double x = point[i].X;
|
|
double y = point[i].Y;
|
|
sumCodeviates += x * y;
|
|
sumOfX += x;
|
|
sumOfY += y;
|
|
sumOfXSq += x * x;
|
|
sumOfYSq += y * y;
|
|
}
|
|
|
|
|
|
double count = point.Count;
|
|
double ssX = sumOfXSq - ((sumOfX * sumOfX) / count);
|
|
double ssY = sumOfYSq - ((sumOfY * sumOfY) / count);
|
|
|
|
double rNumerator = (count * sumCodeviates) - (sumOfX * sumOfY);
|
|
double rDenom = (count * sumOfXSq - (sumOfX * sumOfX)) * (count * sumOfYSq - (sumOfY * sumOfY));
|
|
double sCo = sumCodeviates - ((sumOfX * sumOfY) / count);
|
|
|
|
double meanX = sumOfX / count;
|
|
double meanY = sumOfY / count;
|
|
double dblR = rNumerator / Math.Sqrt(rDenom);
|
|
|
|
yIntercept = meanY - ((sCo / ssX) * meanX);
|
|
slope = sCo / ssX;
|
|
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
#region 문자열 처리
|
|
public static string Right(string target, int length)
|
|
{
|
|
if (length <= target.Length) {
|
|
return target.Substring(target.Length - length);
|
|
} else {
|
|
return string.Empty;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public static bool PushButton(object sender, bool bConfirm = true)
|
|
{
|
|
logUnit.SetLog(LogUnit.eLogType.BUTTON, MethodBase.GetCurrentMethod().Name, string.Format("[{0}]-[{1}] button is pushed", (sender as Button).Name, (sender as Button).Text), LogUnit.eLogLevel.MIDDLE);
|
|
if (bConfirm == true) {
|
|
if (DialogResult.No == MessageBox.Show(string.Format("Do you want to do [{0}]?", (sender as Button).Text), "confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) {
|
|
logUnit.SetLog(LogUnit.eLogType.BUTTON, MethodBase.GetCurrentMethod().Name, string.Format("[{0}]-[{1}] button is canceled", (sender as Button).Name, (sender as Button).Text), LogUnit.eLogLevel.MIDDLE);
|
|
return false;
|
|
}
|
|
logUnit.SetLog(LogUnit.eLogType.BUTTON, MethodBase.GetCurrentMethod().Name, string.Format("[{0}]-[{1}] button is confirmed", (sender as Button).Name, (sender as Button).Text), LogUnit.eLogLevel.MIDDLE);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
#region Xml 읽고 쓰는 함수
|
|
public class XmlSerializable : System.Attribute
|
|
{
|
|
public XmlSerializable() { }
|
|
}
|
|
|
|
public class XmlUtil
|
|
{
|
|
public static void AddProperty(string name, object value, XmlWriter wr)
|
|
{
|
|
string svalue = string.Empty;
|
|
|
|
if (value is string) {
|
|
svalue = value as string;
|
|
}
|
|
|
|
if (svalue.Length == 0 && value.GetType() == typeof(float)) {
|
|
svalue = XmlConvert.ToString(Math.Round((float)value, 8));
|
|
}
|
|
if (svalue.Length == 0 && value.GetType() == typeof(double)) {
|
|
svalue = XmlConvert.ToString(Math.Round((double)value, 8));
|
|
}
|
|
if (svalue.Length == 0) {
|
|
svalue = value.ToString();
|
|
}
|
|
|
|
wr.WriteStartElement("property");
|
|
wr.WriteAttributeString("name", name);
|
|
wr.WriteAttributeString("value", svalue);
|
|
wr.WriteEndElement();
|
|
}
|
|
public static void ParseProperty(XmlElement node, object dataobject)
|
|
{
|
|
if (node.Name != "property")
|
|
return;
|
|
|
|
string fieldname = node.GetAttribute("name");
|
|
string svalue = node.GetAttribute("value");
|
|
if (fieldname.Length == 0 || svalue.Length == 0)
|
|
return;
|
|
|
|
PropertyInfo info = CommonPropertyUtil.GetProperty(dataobject, fieldname);
|
|
if (info == null || info.CanWrite == false)
|
|
return;
|
|
try {
|
|
object value = PropertyUtil.ChangeType(svalue, info.PropertyType);
|
|
if (value != null)
|
|
info.SetValue(dataobject, value, null);
|
|
} catch { };
|
|
}
|
|
public static void ParseProperties(XmlElement itemnode, object dataobject)
|
|
{
|
|
foreach (XmlElement propertynode in itemnode.ChildNodes)
|
|
XmlUtil.ParseProperty(propertynode, dataobject);
|
|
}
|
|
public static void WriteProperties(object dataobject, XmlWriter wr)
|
|
{
|
|
foreach (PropertyInfo propertyInfo in dataobject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
|
|
XmlSerializable attr = (XmlSerializable)Attribute.GetCustomAttribute(propertyInfo, typeof(XmlSerializable));
|
|
if (attr != null) {
|
|
string name = propertyInfo.Name;
|
|
object value = propertyInfo.GetValue(dataobject, null);
|
|
if (value != null) {
|
|
AddProperty(name, value, wr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class PropertyUtil
|
|
{
|
|
public static object ChangeType(object value, Type type)
|
|
{
|
|
if (type == typeof(RectangleF))
|
|
return CommonPropertyUtil.Parse(value.ToString(), type);
|
|
if (type == typeof(Rectangle))
|
|
return CommonPropertyUtil.Parse(value.ToString(), type);
|
|
if (type == typeof(PointF))
|
|
return CommonPropertyUtil.Parse(value.ToString(), type);
|
|
return CommonPropertyUtil.ChangeType(value, type);
|
|
}
|
|
}
|
|
|
|
public class CommonPropertyUtil
|
|
{
|
|
private static PropertyInfo GetNestedProperty(object dataobject, string[] nestedfields, int curindex, ref object nestedDataObject)
|
|
{
|
|
nestedDataObject = dataobject;
|
|
string fieldname = nestedfields[curindex];
|
|
PropertyInfo property = GetProperty(dataobject, fieldname);
|
|
if (property == null)
|
|
return null;
|
|
dataobject = property.GetValue(dataobject, null);
|
|
curindex++;
|
|
if (curindex == nestedfields.Length)
|
|
return property;
|
|
return GetNestedProperty(dataobject, nestedfields, curindex, ref nestedDataObject);
|
|
}
|
|
public static PropertyInfo GetNestedProperty(object dataobject, ref object nestedDataObject, string fullFieldname)
|
|
{
|
|
string[] names = fullFieldname.Split('.');
|
|
return GetNestedProperty(dataobject, names, 0, ref nestedDataObject);
|
|
}
|
|
public static PropertyInfo GetNestedProperty(ref object dataobject, string fullFieldname)
|
|
{
|
|
return GetNestedProperty(dataobject, ref dataobject, fullFieldname);
|
|
}
|
|
|
|
public static PropertyInfo GetProperty(object dataobject, string propertyname)
|
|
{
|
|
if (dataobject == null)
|
|
return null;
|
|
return GetProperty(dataobject.GetType(), propertyname);
|
|
}
|
|
public static PropertyInfo GetProperty(Type dataobjecttype, string propertyname)
|
|
{
|
|
MemberInfo[] members = dataobjecttype.GetMember(propertyname);
|
|
foreach (MemberInfo member in members) {
|
|
PropertyInfo property = (member as PropertyInfo);
|
|
if (property != null)
|
|
return property;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static bool IsPrimitive(object obj)
|
|
{
|
|
if (obj == null)
|
|
return false;
|
|
Type type = obj.GetType();
|
|
if (type.IsPrimitive || type.IsEnum || type == typeof(string))
|
|
return true;
|
|
return false;
|
|
}
|
|
public static object ChangeType(object value, Type type)
|
|
{
|
|
if (value.GetType() == type)
|
|
return value;
|
|
//if (IsClass(value))
|
|
//{
|
|
// if (value.GetType().IsSubclassOf(type))
|
|
// return value;
|
|
// return value;
|
|
//}
|
|
if (value.GetType() == typeof(string) && type.IsEnum) {
|
|
try {
|
|
return Enum.Parse(type, value.ToString());
|
|
} catch {
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if (type.IsPrimitive == false) {
|
|
object obj = Parse(value.ToString(), type);
|
|
if (obj != null)
|
|
return obj;
|
|
}
|
|
try {
|
|
return Convert.ChangeType(value, type);
|
|
} catch { }
|
|
return null;
|
|
}
|
|
static public object Parse(string value, Type type)
|
|
{
|
|
if (type == typeof(System.Drawing.SizeF))
|
|
return Parse(new System.Drawing.SizeF(0, 0), value);
|
|
if (type == typeof(System.Drawing.Size))
|
|
return Parse(new System.Drawing.Size(0, 0), value);
|
|
if (type == typeof(System.Drawing.PointF))
|
|
return Parse(new System.Drawing.PointF(0, 0), value);
|
|
if (type == typeof(System.Drawing.Point))
|
|
return Parse(new System.Drawing.Point(0, 0), value);
|
|
if (type == typeof(System.Drawing.Rectangle))
|
|
return Parse(new System.Drawing.Rectangle(0, 0, 10, 10), value);
|
|
if (type == typeof(System.Drawing.Color)) {
|
|
value = value.Replace("Color ", "");
|
|
value = value.Trim(new char[] { '[', ']' });
|
|
System.Drawing.Color c = System.Drawing.Color.FromName(value);
|
|
if (c.IsKnownColor)
|
|
return c;
|
|
ColorWrapper color = new ColorWrapper();
|
|
Parse(color, value);
|
|
return color.Color;
|
|
}
|
|
if (type == typeof(System.Drawing.RectangleF)) {
|
|
return Parse(new System.Drawing.RectangleF(0, 0, 0, 0), value);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static void ParseProperty(string fieldname, string svalue, object dataobject)
|
|
{
|
|
if (fieldname.Length == 0 || svalue.Length == 0)
|
|
return;
|
|
|
|
PropertyInfo info = GetProperty(dataobject, fieldname);
|
|
if (info == null || info.CanWrite == false)
|
|
return;
|
|
try {
|
|
object value = ChangeType(svalue, info.PropertyType);
|
|
if (value != null)
|
|
info.SetValue(dataobject, value, null);
|
|
} catch { };
|
|
}
|
|
public static object Parse(object obj, string valuestring)
|
|
{
|
|
// string will be in format '{property=value, property=value}'
|
|
valuestring = valuestring.Trim(new char[] { '{', '}' });
|
|
string[] properties = valuestring.Split(',');
|
|
foreach (string propertyvalue in properties) {
|
|
string[] propvaluepair = propertyvalue.Split('=');
|
|
if (propvaluepair.Length != 2)
|
|
continue;
|
|
string fieldname = propvaluepair[0].Trim();
|
|
string value = propvaluepair[1].Trim();
|
|
ParseProperty(fieldname, value, obj);
|
|
}
|
|
return obj;
|
|
}
|
|
internal class ColorWrapper
|
|
{
|
|
int a = 0, r = 0, g = 0, b = 0;
|
|
public int A {
|
|
get { return a; }
|
|
set { a = value; }
|
|
}
|
|
public int R {
|
|
get { return r; }
|
|
set { r = value; }
|
|
}
|
|
public int G {
|
|
get { return g; }
|
|
set { g = value; }
|
|
}
|
|
public int B {
|
|
get { return b; }
|
|
set { b = value; }
|
|
}
|
|
public System.Drawing.Color Color {
|
|
get { return System.Drawing.Color.FromArgb(a, r, g, b); }
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|