247 lines
7.4 KiB
C#
247 lines
7.4 KiB
C#
/*
|
||
* 本代码受中华人民共和国著作权法保护,作者仅授权下载代码之人在学习和交流范围内
|
||
* 自由使用与修改代码;欲将代码用于商业用途的,请与作者联系。
|
||
* 使用本代码请保留此处信息。作者联系方式:ping3108@163.com, 欢迎进行技术交流
|
||
*/
|
||
|
||
using System;
|
||
//忽略没有注释警告
|
||
#pragma warning disable 1591
|
||
namespace MGdu.WinFormUI
|
||
{
|
||
public class CutePointAndValuePresenter
|
||
{
|
||
#region 内部变量
|
||
|
||
int eggCount = 10;
|
||
int markCount = 10;
|
||
bool fcp;
|
||
|
||
double averageEggsInEachGab;
|
||
int firstMarkN;
|
||
int lastMarkN;
|
||
|
||
#endregion
|
||
|
||
#region 构造函数
|
||
|
||
public CutePointAndValuePresenter()
|
||
{
|
||
UpdateEggAndMarkInfo();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 公开的属性,方法
|
||
|
||
public int PointCount
|
||
{
|
||
get
|
||
{
|
||
return fcp ? eggCount : markCount;
|
||
}
|
||
}
|
||
|
||
public int ValueCount
|
||
{
|
||
get
|
||
{
|
||
return fcp ? markCount : eggCount;
|
||
}
|
||
}
|
||
|
||
public void SetPointAndValueCount(int pointCount, int valueCount)
|
||
{
|
||
if (pointCount < 1)
|
||
pointCount = 1;
|
||
if (valueCount < 1)
|
||
valueCount = 1;
|
||
if (pointCount >= valueCount)
|
||
{
|
||
fcp = true;
|
||
eggCount = pointCount;
|
||
markCount = valueCount;
|
||
}
|
||
else
|
||
{
|
||
fcp = false;
|
||
eggCount = valueCount;
|
||
markCount = pointCount;
|
||
}
|
||
UpdateEggAndMarkInfo();
|
||
}
|
||
|
||
public void GetPointIndexFromValueIndex(int vIndex, out int pIndexFrom, out int pIndexTo)
|
||
{
|
||
|
||
if (fcp)
|
||
{
|
||
if (vIndex < 0 || vIndex > markCount - 1)
|
||
throw new ArgumentOutOfRangeException("vIndex");
|
||
|
||
GetEggsIndexFromMarkIndex(vIndex, out pIndexFrom, out pIndexTo);
|
||
}
|
||
else
|
||
{
|
||
if (vIndex < 0 || vIndex > eggCount - 1)
|
||
throw new ArgumentOutOfRangeException("vIndex");
|
||
|
||
GetMarkIndexFromEggIndex(vIndex, out pIndexFrom);
|
||
pIndexTo = pIndexFrom;
|
||
}
|
||
}
|
||
|
||
public void GetValueIndexFromPointIndex(int pIndex, out int vIndexFrom, out int vIndexTo)
|
||
{
|
||
if (fcp)
|
||
{
|
||
if (pIndex < 0 || pIndex > eggCount - 1)
|
||
throw new ArgumentOutOfRangeException("pIndex");
|
||
|
||
GetMarkIndexFromEggIndex(pIndex, out vIndexFrom);
|
||
vIndexTo = vIndexFrom;
|
||
}
|
||
else
|
||
{
|
||
if (pIndex < 0 || pIndex > markCount - 1)
|
||
throw new ArgumentOutOfRangeException("pIndex");
|
||
|
||
GetEggsIndexFromMarkIndex(pIndex, out vIndexFrom, out vIndexTo);
|
||
}
|
||
}
|
||
|
||
public void GetExactPointIndexFromValueIndex(int vIndex, out int pIndex)
|
||
{
|
||
int pIndex2;
|
||
GetPointIndexFromValueIndex(vIndex, out pIndex, out pIndex2);
|
||
int maxIndex = fcp ? markCount - 1 : eggCount - 1;
|
||
if (vIndex == maxIndex)
|
||
pIndex = pIndex2;
|
||
else if (vIndex != 0)
|
||
pIndex = (pIndex + pIndex2) / 2;
|
||
}
|
||
|
||
public void GetExactValueIndexFromPointIndex(int pIndex, out int vIndex)
|
||
{
|
||
int vIndex2;
|
||
GetValueIndexFromPointIndex(pIndex, out vIndex, out vIndex2);
|
||
int maxIndex = fcp ? eggCount - 1 : markCount - 1;
|
||
if (pIndex == maxIndex)
|
||
vIndex = vIndex2;
|
||
else if (pIndex != 0)
|
||
vIndex = (vIndex + vIndex2) / 2;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 内部函数
|
||
|
||
private int GetUpRoundedHalfValue(int a)
|
||
{
|
||
int t = a / 2;
|
||
if (a % 2 != 0)
|
||
t++;
|
||
return t;
|
||
}
|
||
|
||
private int EggsCount(int markIndex)
|
||
{
|
||
return (markIndex + 1) +
|
||
(int)Math.Round(averageEggsInEachGab * ((double)markIndex + 0.5), MidpointRounding.AwayFromZero);
|
||
}
|
||
|
||
private void UpdateEggAndMarkInfo()
|
||
{
|
||
if (markCount == 1)
|
||
{
|
||
firstMarkN = eggCount;
|
||
return;
|
||
}
|
||
if (markCount == 2)
|
||
{
|
||
firstMarkN = GetUpRoundedHalfValue(eggCount);
|
||
lastMarkN = eggCount / 2;
|
||
return;
|
||
}
|
||
|
||
int remainEggs = eggCount - markCount;
|
||
int gabs = markCount - 1;
|
||
averageEggsInEachGab = (double)remainEggs / (double)gabs;
|
||
firstMarkN = EggsCount(0);
|
||
lastMarkN = eggCount - EggsCount(markCount - 2);
|
||
}
|
||
|
||
private void GetEggsIndexFromMarkIndex(int markIndex, out int eggIndexFrom, out int eggIndexTo)
|
||
{
|
||
if (markIndex == 0)
|
||
{
|
||
eggIndexFrom = 0;
|
||
eggIndexTo = firstMarkN - 1;
|
||
return;
|
||
}
|
||
if (markIndex == markCount - 1)
|
||
{
|
||
eggIndexTo = eggCount - 1;
|
||
eggIndexFrom = eggIndexTo - lastMarkN + 1;
|
||
return;
|
||
}
|
||
eggIndexFrom = EggsCount(markIndex - 1);
|
||
eggIndexTo = EggsCount(markIndex) - 1;
|
||
}
|
||
|
||
private void GetMarkIndexFromEggIndex(int eggIndex, out int markIndex)
|
||
{
|
||
if (eggIndex < firstMarkN)
|
||
{
|
||
markIndex = 0;
|
||
return;
|
||
}
|
||
if (eggIndex >= (eggCount - lastMarkN))
|
||
{
|
||
markIndex = markCount - 1;
|
||
return;
|
||
}
|
||
|
||
//double rst = ((double)eggIndex + averageEggsInEachGab * 0.5) / (1 + averageEggsInEachGab);
|
||
//markIndex = (int)rst;
|
||
|
||
markIndex = (int)(((double)eggIndex + averageEggsInEachGab * 0.5) / (1 + averageEggsInEachGab));
|
||
if (!IsRightEgg(markIndex, eggIndex))
|
||
{
|
||
if (markIndex == 1)
|
||
markIndex++;
|
||
else if (markIndex == markCount - 2)
|
||
markIndex--;
|
||
else
|
||
{
|
||
if (IsRightEgg(markIndex - 1, eggIndex))
|
||
markIndex--;
|
||
else if (IsRightEgg(markIndex + 1, eggIndex))
|
||
markIndex++;
|
||
else
|
||
{
|
||
string msg = "Inner error in CutePointAndValuePresenter.GetMarkIndexFromEggIndex(), " +
|
||
"\r\n" + "can't find the correct markindex, please contact the author and " +
|
||
"report this error with the following data: " + "\r\n" +
|
||
"eggCount: " + eggCount.ToString() + "\r\n" +
|
||
"markCount: " + markCount.ToString() + "\r\n" +
|
||
"eggIndex: " + eggIndex.ToString();
|
||
|
||
throw new Exception(msg);
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
private bool IsRightEgg(int markIndex, int eggIndex)
|
||
{
|
||
int eggIndex1 = EggsCount(markIndex - 1);
|
||
int eggIndex2 = EggsCount(markIndex) - 1;
|
||
return (eggIndex1 <= eggIndex) && (eggIndex <= eggIndex2);
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
}
|