前面讲到了相对坐标系工具,但没有实现它,现在补齐。
一个窗口,就有一个坐标系,但是,你动不了它,它始终是(0,0),所以有时,我们需要一个相对坐标系,可以拖动,也可以旋转,因为他能提供便利,所以我们就制作了他,特别要指出,当这个相对坐标系工具位于感兴趣区域中心(focus)时,而且与你期望的xy轴重叠时,你就会忘记了原来的那个(0,0)点。从某种意义上讲,相对坐标系不亚于相对论,我这样给你比喻,或许形象一些,如果说窗口(0,0)是整个世界空间(唯物世界),那么相对坐标系就是我的局部世界空间(唯心世界,因为他含有感兴趣和期望,这不就是人(动物)才会有的吗?想说明什么?很简单,心动;人工智能是什么?模拟意识出牌,意识是什么?心动也!孩子现在特别喜欢玩Minecraft,希望以后他能看到此篇)。这个观点实在是太震撼!当你有一种感悟时,他就会提供一种源源不断的动力,促使你在味同嚼蜡中前行!真的是味同嚼蜡吗?非也!扯远了吗?没有。没有兴趣,就不会有感悟;没有感悟,行动何在?!
做一件事情,要看到自己的长处,要扬长避短,才会立于不败;长处像平台,也像逻辑,按着逻辑,会走向下一步平台。日积月累,终有收获。当我明白这个道理时,失败累累!孩子都会打酱油了。所以我有线图像工具这个平台,趁热打铁,完成一个相对坐标系工具。
总结一下,我们前面完成一种工具,有三个类,一,底层画类;二,中层操作类;三,上层感知类及附加。在此,我们只需提供一个唯心世界立锥之点,所以上层感知类就不要了。人生相似(工具一样),侧重不同。下面是设计的相对坐标系工具底层画类RoiBase3:
public class RoiBase3//for coordiate
{//服务于相对坐标系
public mg_line RcCentreLine;//-------
public mg_line startLine;//|-------
public PointF m_RcCenter;
public bool m_bconvert = false;
public RoiBase3()//构造函数
{
PointF start = new PointF(10, 40);
PointF end = new PointF(70, 40);
RcCentreLine = new mg_line(start, end);
m_RcCenter = new PointF((start.X + end.X) / (float)2, (start.Y + end.Y) / (float)2);
start = new PointF(10, 40);
end = new PointF(10, 70);
startLine = new mg_line(start, end);
}
public float getLineLength(mg_line templine)//获取线长度,前面出现过
{
float xx = templine.pt_start.X - templine.pt_end.X;
float yy = templine.pt_start.Y - templine.pt_end.Y;
return (float)Math.Sqrt(xx * xx + yy * yy);
}
public void RoiReset(float deltaChang, float deltaKuan)//重置
{
PointF start = new PointF(RcCentreLine.pt_start.X, RcCentreLine.pt_start.Y);
PointF end = new PointF(RcCentreLine.pt_start.X + 60 + deltaChang, RcCentreLine.pt_start.Y);
RcCentreLine = new mg_line(start, end);
m_RcCenter = new PointF((start.X + end.X) / (float)2, (start.Y + end.Y) / (float)2);
start = new PointF(RcCentreLine.pt_start.X, RcCentreLine.pt_start.Y);
if (m_bconvert)
{
end = new PointF(RcCentreLine.pt_start.X, RcCentreLine.pt_start.Y - 30 - deltaKuan);
}
else
{
end = new PointF(RcCentreLine.pt_start.X, RcCentreLine.pt_start.Y + 30 + deltaKuan);
}
startLine = new mg_line(start, end);
}
public void convertCoordinate()//以x轴翻转
{
m_bconvert = true;
// 1,先到原始状态
float chang = getLineLength(RcCentreLine);//获取直线长度
float kuan = getLineLength(startLine);//获取直线宽度
chang = chang - 60;//原来长度60
kuan = kuan - 30;//原来宽度30
// 2,增加长度和宽度
RoiReset(chang, kuan);
// 3,旋转到当前角度
RcCentreLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
startLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
//4,移动x=0,y=0
}
public void retCommonCoordinate()//以x轴翻转
{
m_bconvert = false;
// 1,先到原始状态
float chang = getLineLength(RcCentreLine);//获取直线长度
float kuan = getLineLength(startLine);//获取直线宽度
chang = chang - 60;//原来长度60
kuan = kuan - 30;//原来宽度30
// 2,增加长度和宽度
RoiReset(chang, kuan);
// 3,旋转到当前角度
RcCentreLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
startLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
//4,移动x=0,y=0
}
public void DrawLineAndRect(Graphics g, Pen p)//画出示意及拖动小矩形
{
g.DrawLine(p, RcCentreLine.pt_start, RcCentreLine.pt_end);
g.DrawLine(p, startLine.pt_start, startLine.pt_end);
//Right
g.DrawRectangle(p, (int)RcCentreLine.pt_end.X - 5, (int)RcCentreLine.pt_end.Y - 5, 10, 10);
string str1 = "X+";
Font drawfont = new Font("Arial", 9);
g.DrawString(str1, drawfont, Brushes.Brown, RcCentreLine.pt_end.X - 5, RcCentreLine.pt_end.Y + 5);
//left
g.DrawRectangle(p, (int)RcCentreLine.pt_start.X - 5, (int)RcCentreLine.pt_start.Y - 5, 10, 10);
//tolerance
g.DrawRectangle(p, startLine.pt_end.X - 5, startLine.pt_end.Y - 5, 10, 10);
if (!m_bconvert)
{
str1 = "O";
drawfont = new Font("Arial", 9);
g.DrawString(str1, drawfont, Brushes.Brown, RcCentreLine.pt_start.X + 5, RcCentreLine.pt_start.Y + 5);
str1 = "Y+";
drawfont = new Font("Arial", 9);
g.DrawString(str1, drawfont, Brushes.Brown, startLine.pt_end.X - 5, startLine.pt_end.Y + 5);
}
else
{
//g.DrawRectangle(p, (int)RcCentreLine.pt_start.X - 5, (int)RcCentreLine.pt_start.Y - 5, 10, 10);
str1 = "O";
drawfont = new Font("Arial", 9);
g.DrawString(str1, drawfont, Brushes.Brown, RcCentreLine.pt_start.X + 5, RcCentreLine.pt_start.Y + 5);
str1 = "Y+";
drawfont = new Font("Arial", 9);
g.DrawString(str1, drawfont, Brushes.Brown, startLine.pt_end.X - 15, startLine.pt_end.Y - 15);
}
}
public void Drag(PointF point)//拖动操作
{
PointF delta = new PointF(point.X - RcCentreLine.pt_start.X, point.Y - RcCentreLine.pt_start.Y);
RcCentreLine.Move(delta);
startLine.Move(delta);
this.m_RcCenter.X = (float)(RcCentreLine.pt_start.X / 2.0 + RcCentreLine.pt_end.X / 2.0);
this.m_RcCenter.Y = (float)(RcCentreLine.pt_start.Y / 2.0 + RcCentreLine.pt_end.Y / 2.0);
// return new PointF(RcCentreLine.pt_start.X, RcCentreLine.pt_start.Y);
}
public void DragOrg(PointF point, double tempjiaodu)//拖动原点
{//RcCentreLine和startLine两条线相交处是原点
PointF delta = new PointF(point.X - RcCentreLine.pt_start.X, point.Y - RcCentreLine.pt_start.Y);
// PointF delta = new PointF(point.X , point.Y);
RcCentreLine.Move(delta);
startLine.Move(delta);
RcCentreLine.Rotate(RcCentreLine.pt_start, -tempjiaodu * 3.1415926 / 180.0);
startLine.Rotate(RcCentreLine.pt_start, -tempjiaodu * 3.1415926 / 180.0);
m_jiaodu += -tempjiaodu * 3.1415926 / 180.0;
if (m_jiaodu < -2 * 3.1415926) { m_jiaodu = m_jiaodu + 2 * 3.1415926; }
//RcCentreLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
//startLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
}
public void DragOrgEx(PointF point, double tempjiaodu)//拖动原点改进(extend)
{
m_bconvert = false;
// 1,先到原始状态
float chang = getLineLength(RcCentreLine);//获取直线长度
float kuan = getLineLength(startLine);//获取直线宽度
chang = chang - 60;//原来长度60
kuan = kuan - 30;//原来宽度30
// 2,增加长度和宽度
RoiReset(chang, kuan);
// 3,旋转到当前角度
//RcCentreLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
//startLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
double a = tempjiaodu * 3.1415926 / 180.0;
m_jiaodu = a;
RcCentreLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
startLine.Rotate(RcCentreLine.pt_start, m_jiaodu);
//4,移动x=0,y=0
PointF delta = new PointF(point.X - RcCentreLine.pt_start.X, point.Y - RcCentreLine.pt_start.Y);
RcCentreLine.Move(delta);
startLine.Move(delta);
}
public int IsPointInRect(PointF point)//是否在操作框内
{
if (point.X <= RcCentreLine.pt_start.X + 5 && point.X >= RcCentreLine.pt_start.X - 5
&& point.Y >= RcCentreLine.pt_start.Y - 5 && point.Y <= RcCentreLine.pt_start.Y + 5)
{
return (int)E_HANDLES.E_HANDLE_INSIDE;//操作一,拖动原点
}
else if (point.X <= startLine.pt_end.X + 5 && point.X >= startLine.pt_end.X - 5
&& point.Y >= startLine.pt_end.Y - 5 && point.Y <= startLine.pt_end.Y + 5)
{
return (int)E_HANDLES.E_HANDLE_SOUTH;//操作二,拖动弹性
}
else if (point.X <= RcCentreLine.pt_end.X + 5 && point.X >= RcCentreLine.pt_end.X - 5
&& point.Y >= RcCentreLine.pt_end.Y - 5 && point.Y <= RcCentreLine.pt_end.Y + 5)
{//操作三,拖动旋转
return (int)E_HANDLES.E_HANDLE_EAST;// E_HANDLE_EAST,3
}
else
{
return 0;
}
}
public double jiaoduAndxiangxian(double x_temp, double y_temp)
{
...................
//前面工具已经实现
}
//public PointF NewDragXYandRotate(PointF point)
public double m_jiaodu = 0;
public void DragXYandRotate(PointF point)//注意参考ROI for self Rect20160628
{//操作三,拖动旋转带来的工具变化更新
// double k, k1;
double fenziY, fenmuX;
fenziY = (RcCentreLine.pt_end.Y - RcCentreLine.pt_start.Y);
fenmuX = RcCentreLine.pt_end.X - RcCentreLine.pt_start.X;
double thetatheta = 0;
thetatheta = jiaoduAndxiangxian(fenmuX, fenziY);
RcCentreLine.updatePend(point);
fenziY = (RcCentreLine.pt_end.Y - RcCentreLine.pt_start.Y);
fenmuX = RcCentreLine.pt_end.X - RcCentreLine.pt_start.X;
double thetatheta1 = 0;
thetatheta1 = jiaoduAndxiangxian(fenmuX, fenziY);
double DeltaTheta1 = 0;
DeltaTheta1 = thetatheta1 - thetatheta;
startLine.Rotate(RcCentreLine.pt_start, DeltaTheta1);
//////////////////////////////
m_jiaodu = thetatheta1;
//m_RcCenter
PointF start = (RcCentreLine.pt_start);
PointF end = (RcCentreLine.pt_end);
m_RcCenter = new PointF((start.X + end.X) / (float)2, (start.Y + end.Y) / (float)2);
// return new PointF((float)thetatheta1, (float)DeltaTheta1);
}
public void Rotation(double temp_jiaodu)//旋转
{
RcCentreLine.Rotate(RcCentreLine.pt_start, temp_jiaodu);
startLine.Rotate(RcCentreLine.pt_start, temp_jiaodu);
m_jiaodu = temp_jiaodu;
}
public PointF mapPoint(PointF inputPt)//屏幕坐标系没有翻转(flip),仅仅是旋转,无法到达笛卡尔系
{
float tempx = inputPt.X - RcCentreLine.pt_start.X;
float tempy = inputPt.Y - RcCentreLine.pt_start.Y;
mg_line templine = new mg_line(new PointF(0, 0), new PointF(tempx, tempy));
templine.Rotate(templine.pt_start, -m_jiaodu);
return templine.pt_end;
}
public PointF mapPoint(PointF inputPt, float scale)//屏幕坐标系没有翻转(flip),仅仅是旋转,无法到达笛卡尔系
{//201706111423//scale=org(1024)/zoom(512)=2
float tempx = inputPt.X - RcCentreLine.pt_start.X * scale;
float tempy = inputPt.Y - RcCentreLine.pt_start.Y * scale;
mg_line templine = new mg_line(new PointF(0, 0), new PointF(tempx, tempy));
templine.Rotate(templine.pt_start, -m_jiaodu);
return templine.pt_end;
}
public PointF invertmapPoint(PointF inputPt)//逆映射1
{
mg_line templine = new mg_line(new PointF(0, 0), inputPt);
templine.Rotate(templine.pt_start, m_jiaodu);
// templine.pt_end.X + RcCentreLine.pt_start.X;
// templine.pt_end.Y + RcCentreLine.pt_start.Y;
return new PointF(templine.pt_end.X + RcCentreLine.pt_start.X, templine.pt_end.Y + RcCentreLine.pt_start.Y);
}
public PointF mapPointTest(PointF inputPt)//针对屏幕坐标系翻转(flip)后的笛卡尔系
{
float tempx = inputPt.X - RcCentreLine.pt_start.X;
float tempy = (inputPt.Y - RcCentreLine.pt_start.Y);
mg_line templine = new mg_line(new PointF(0, 0), new PointF(tempx, tempy));
templine.Rotate(templine.pt_start, -m_jiaodu);
return new PointF(templine.pt_end.X, -templine.pt_end.Y);
}
public PointF invertmapPointTest(PointF inputPt)//逆映射2
{
inputPt = new PointF(inputPt.X, -inputPt.Y);
mg_line templine = new mg_line(new PointF(0, 0), inputPt);
templine.Rotate(templine.pt_start, m_jiaodu);
// templine.pt_end.X + RcCentreLine.pt_start.X;
// templine.pt_end.Y + RcCentreLine.pt_start.Y;
return new PointF(templine.pt_end.X + RcCentreLine.pt_start.X, templine.pt_end.Y + RcCentreLine.pt_start.Y);
}
public void DragTolerancey(PointF point)//程序逻辑不对20160627,已经更正
{//操作二,拖动弹性带来的工具更新变化
double k2 = 0; double k = 0;
PointF QQ = new PointF();
PointF AA = startLine.pt_end;
if ((RcCentreLine.pt_end.X - RcCentreLine.pt_start.X) == 0)
{
QQ.X = point.X;
QQ.Y = AA.Y;
//返回前x轴需要更新20160702
//if ((AA.X - startLine.pt_start.X) * (QQ.X - startLine.pt_start.X) < 0)
//{
// RcCentreLine.Rotate(RcCentreLine.pt_start, 3.1415926);//不能彻底解决问题201607022126
//}
if ((AA.X - startLine.pt_start.X) * (QQ.X - startLine.pt_start.X) > 2)
{
startLine.updatePstart(startLine.pt_start);//此方法奏效201607022159
startLine.updatePend(QQ);
}
return;
}
if ((startLine.pt_start.X - AA.X) == 0)
{
QQ.X = AA.X;
QQ.Y = point.Y;
}
else
{
k2 = (RcCentreLine.pt_end.Y - RcCentreLine.pt_start.Y) / (RcCentreLine.pt_end.X - RcCentreLine.pt_start.X);
k = (startLine.pt_start.Y - AA.Y) / (startLine.pt_start.X - AA.X);//计算一个k就可以了,k*k2=-1;20160701暂时不改变
QQ.X = (float)((AA.Y - point.Y + k2 * point.X - k * AA.X) / (k2 - k));
QQ.Y = (float)(AA.Y + k * QQ.X - k * AA.X);
}
//返回前x轴需要更新20160702//
if ((AA.Y - startLine.pt_start.Y) * (QQ.Y - startLine.pt_start.Y) > 2)
{
// RcCentreLine.Rotate(RcCentreLine.pt_start, 3.1415926);
startLine.updatePstart(startLine.pt_start);
startLine.updatePend(QQ);
}
}
}
(未完,待续............)