线图像的第四变,相对坐标系工具(一)

前面讲到了相对坐标系工具,但没有实现它,现在补齐。

一个窗口,就有一个坐标系,但是,你动不了它,它始终是(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);
            }
        }
    }

(未完,待续............)

猜你喜欢

转载自blog.csdn.net/ganggangwawa/article/details/89531007
今日推荐