下图中圆标注的点都知道其坐标点,
拖动红色虚线蓝色加圆标注注点,使矩形的大小变大.
要怎么计算出蓝色矩形的标出的坐标点.

解决方案 »

  1.   

    http://www.codeproject.com/KB/graphics/drawtools.aspx
      

  2.   

    以左上角为坐标圆点,其实就是两条直线
    直线的方程式:y=kx+b(这里k是一负数),知道两个点就可以求得k与b(两点确定一条直线)
    平行移动时,k是不变的,三点共线,由移动的距离便可求得
      

  3.   

    完全可以实现你的要求。
       /// <summary>
            ///  已知平行四边形的三点 求第四个点
            ///  假设3个点为A(a1,a2),B(b1,b2),C(c1,c2) 此处选择第三种情况
            ///  第四个点可以是D(b1+c1-a1,b2+c2-a2),D(a1+b1-c1,a2+b2-c2),D(a1+c1-b1,a2+b2-c2)
            /// </summary>
            /// <param name="p1"></param>
            /// <param name="p2"></param>
            /// <param name="p3"></param>
            /// <returns></returns>
            public static Point MovingLinePoint(Point p1, Point p2, Point p3)
            {
                /* 
                 * 平行四边形如下
                 * 
                 *        P1*******************P4
                 *         *                 *
                 *        *                 *
                 *     P2*******************P3  
                 * 
                 */
                Point p4 = Point.Empty;
                if (!(p1.IsEmpty && p2.IsEmpty && p3.IsEmpty))
                {
                    p4.X = p1.X + p3.X - p2.X;
                    p4.Y = p1.Y + p3.Y - p2.Y;
                }
                return p4;
            }
    类的作用神马的已经标清了,s1,s2,P2自己定义随便,Panel假设为你的画板,假设你所说的这条虚线有pointStart和pointEnd,则画出这条线为:
    private void Panel_MouseDown(object sender, MouseEventArgs e){P2 = e.Location;
    s1 = 虚线.pointStart;
                        s2 = 虚线.pointEnd;}
    private void DrawPanel_MouseMove(object sender, MouseEventArgs e)
            {
       虚线.pointStart = CCHP.BLL.DoCalculate.MovingLinePoint(e.Location, P2, s1);
                            虚线.pointEnd = CCHP.BLL.DoCalculate.MovingLinePoint(e.Location, P2, s2);
    Panel.Invalidate();
            }
    private void DrawPanel_MouseUp(object sender, MouseEventArgs e)
            {//这里自己想想随便写}
    估计排版很BT,如果有什么问题,随时交流。。我代码很乱的。
      

  4.   

            private void Panel_MouseDown(object sender, MouseEventArgs e)
            {
                //....
                P2 = e.Location;
                s1 = 虚线.pointStart;
                s2 = 虚线.pointEnd;
                //...
            }
            private void Panel_MouseMove(object sender, MouseEventArgs e)
            {
                //...
                虚线.pointStart = CCHP.BLL.DoCalculate.MovingLinePoint(e.Location, P2, s1);
                虚线.pointEnd = CCHP.BLL.DoCalculate.MovingLinePoint(e.Location, P2, s2);
                Panel.Invalidate();
                //...
            }
            private void Panel_MouseUp(object sender, MouseEventArgs e)
            {
                //...
                //这里自己想想随便写
                //...
            }
    重新排好。
      

  5.   

    我正好也遇到这样一个类似的问题,不过我的实现方法和你不太一样,我不是直接计算旋转以后点的坐标,而是利用Matrix变形以后得到的。关注并期待中……
      

  6.   

    我的思路是这样的,首先,矩形本身并不需要关心旋转的问题,只需要知道正常情况下四个角的坐标,将生成相应的GraphicsPath。在绘制图形时,要先根据指定的参数对矩形所创建的GraphicsPath进行变形,然后再绘制到Graphics上。
    对GraphicsPath的变形主要是旋转,另外如果要考虑旋转中心可以移动,那还涉及到位移。GraphicsPath.Transform方法可以对GraphicsPath中的数据进行变形,此方法的参数Matrix可以指定变形的方式,旋转采用Matrix.RotateAt方法,位移采用Matrix.Translate方法。
    在这种情况下,每个形状实际上可以想向成有两套坐标,一套是原始状态,一套是显示状态,显示状态是通过原始状态变形得到的,因此它应该是只读的。但别扭的是,我们实际在操作的过程中用到的是形状的显示状态,但它又是只读的,因此要必须把用户的操作转换回相应原始状态的数据,这步是最复杂的,也是目前我没有完全做好的。
    这个思路是我在仔细研究了Visio的行为得出来的,其实我也不知道这样的思路是不是正确的,但感觉上应该是对的,只是基础太差完成不了。希望你的问题早点解决,给我一些启发。
      

  7.   

    先得到这个矩形的matrix变换,然后将鼠标点改变为在变换中的鼠标位置,也就是实现去掉变换后矩形的位置和鼠标的点的位置,然后改变矩形的大小和位置,最后再通过matrix变换回来,就能得到上面拉升后的效果
      

  8.   


    这些是我的程序中摘录的一些代码,代码很多很乱,但是已经能够实现上述功能,希望能够对你有些帮助。        private void sizeObj(Point mPoint)
            {
                PointF pt, op, mp;
                RectangleF bound, boundEx;
                op = mPoint;
                switch (SelectType)
                {
                    case SelectEnum.Select:
                        mp = m_SelectTool.MatrixMToF(op);
                        mp.X -= m_errWidth;
                        mp.Y -= m_errHeight;
                        bound = m_SelectTool.GetRealBound();
                        boundEx = GetBoundEx(bound);
                        break;
                    case SelectEnum.MultiSelect:
                        mp = op;
                        mp.X -= m_errWidth;
                        mp.Y -= m_errHeight;
                        bound = m_SelectToolsBounds;
                        boundEx = GetBoundEx(bound);
                        break;
                    default:
                        return;
                }
                switch (m_HitNear)
                {
                    case 1://左上
                        pt = new PointF(boundEx.Right, boundEx.Bottom);
                        boundEx = RectangleF.FromLTRB(mp.X, mp.Y, pt.X, pt.Y);
                        break;
                    case 2://右上
                        pt = new PointF(boundEx.Left, boundEx.Bottom);
                        boundEx = RectangleF.FromLTRB(pt.X, mp.Y, mp.X, pt.Y);
                        break;
                    case 3://左下
                        pt = new PointF(boundEx.Right, boundEx.Top);
                        boundEx = RectangleF.FromLTRB(mp.X, pt.Y, pt.X, mp.Y);
                        break;
                    case 4://右下
                        pt = new PointF(boundEx.Left, boundEx.Top);
                        boundEx = RectangleF.FromLTRB(pt.X, pt.Y, mp.X, mp.Y);
                        break;
                    case 5://上中
                        pt = new PointF(boundEx.Right, boundEx.Bottom);
                        boundEx = RectangleF.FromLTRB(boundEx.X, mp.Y, pt.X, pt.Y);
                        break;
                    case 6://下中
                        pt = new PointF(boundEx.Left, boundEx.Top);
                        boundEx = RectangleF.FromLTRB(pt.X, pt.Y, boundEx.Right, mp.Y);
                        break;
                    case 7://左中
                        pt = new PointF(boundEx.Right, boundEx.Bottom);
                        boundEx = RectangleF.FromLTRB(mp.X, boundEx.Top, pt.X, pt.Y);
                        break;
                    case 8://右中
                        pt = new PointF(boundEx.Left, boundEx.Top);
                        boundEx = RectangleF.FromLTRB(pt.X, pt.Y, mp.X, boundEx.Bottom);
                        break;
                    default:
                        return;
                }
                bound = RectangleF.FromLTRB(bound.Width < 0 ? boundEx.Right : boundEx.Left, bound.Height < 0 ? boundEx.Bottom : boundEx.Top,
                            bound.Width < 0 ? boundEx.Left : boundEx.Right, bound.Height < 0 ? boundEx.Top : boundEx.Bottom);
                switch (SelectType)
                {
                    case SelectEnum.Select:
                        m_RealMoveBound = bound;
                        m_SelectTool.SizeObj(Rectangle.Round(bound), Point.Round(pt));
                        break;
                    case SelectEnum.MultiSelect:
                        m_RealMoveBound = bound;
                        SetToolsSizing(Point.Round(pt));
                        break;
                    default:
                        return;
                }
            }        public virtual void SizeObj(Rectangle rect, Point p)
            {
                m_MoveLocation = rect.Location;
                if ((rect.Width == 0) || (rect.Height == 0))
                {
                    m_MoveSize = m_Size;
                }
                else
                {
                    m_MoveSize.Width = rect.Width;
                    m_MoveSize.Height = rect.Height;
                }
                PointF p1, p2;
                float offectX, offectY;
                p1 = MatrixFToM(p);
                p2 = MatrixMoveFToM(p);
                offectX = p1.X - p2.X;
                offectY = p1.Y - p2.Y;
                m_MoveLocation.X += (int)offectX;
                m_MoveLocation.Y += (int)offectY;
            }        public PointF MatrixFToM(PointF mPoint)
            {
                PointF pf;
                using (Matrix matrix = GetMatrix())
                {
                    PointF[] points = { mPoint };
                    matrix.TransformPoints(points);
                    pf = points[0];
                }
                return pf;
            }
            internal protected virtual Matrix GetMoveMatrix()
            {
                Matrix matrix = new Matrix();
                PointF centerf = GetRotateMoveCenterPoinF(m_ScaleWidth, m_ScaleHeight);
                matrix.Rotate(m_MoveAngle);
                matrix.Shear(m_MoveShearX, m_MoveShearY);
                matrix.Translate(-centerf.X, -centerf.Y);
                matrix.Translate(centerf.X, centerf.Y, MatrixOrder.Append);
                return matrix;
            }
            protected PointF GetRotateMoveCenterPoinF(float scaleWidth, float scaleHeight)
            {
                PointF center = GetMoveCenterPoint();
                center.X += (m_MoveSize.Width * scaleWidth);
                center.Y += (m_MoveSize.Height * scaleHeight);
                return center;
            }
            internal protected virtual Matrix GetMatrix()
            {
                Matrix matrix = new Matrix();
                PointF centerf = GetRotateCenterPointF(m_ScaleWidth, m_ScaleHeight);
                matrix.Rotate(m_Angle);
                matrix.Shear(m_ShearX, m_ShearY);
                matrix.Translate(-centerf.X, -centerf.Y);
                matrix.Translate(centerf.X, centerf.Y, MatrixOrder.Append);
                return matrix;
            }
      

  9.   

    实现方法: public DrawRoateRect(int x, int y, int w, int h)
            {
                rectangle.X = x;
                rectangle.Y = y;
                rectangle.Width = w;
                rectangle.Height = h;
                TypeName = ObjectType.RoateRectangle;
                //计算出初始的中心点
                RoatePoint = new PointF((float)rectangle.Width / 2 + rectangle.X, (float)rectangle.Height / 2 + rectangle.Y);
                InitRect();
            }
            
            private void InitRect()
            {
                Trace.WriteLine("Rectangle:"+rectangle.ToString());
                Trace.WriteLine("CenterPoint:"+RoatePoint);
    //按中心点进行旋转
                Matrix matrix = new Matrix();
                matrix.RotateAt(RoateAngle,RoatePoint);
    //添加矩形
                rectPath = new GraphicsPath();
                rectPath.AddRectangle(rectangle);
                rectPath.Transform(matrix);
                //rectPath.Widen(new Pen(LineColor, LineWidth + 5));
    //添加矩形的8个手柄的中心点
                tempPath = new GraphicsPath();
                //handle 1
                tempPath.AddLine(rectangle.X,rectangle.Y,rectangle.X,rectangle.Y);
                //handle 2
                tempPath.AddLine(rectangle.X + rectangle.Width/2,rectangle.Y,rectangle.X + rectangle.Width/2,rectangle.Y);
                //handle 3
                tempPath.AddLine(rectangle.Right,rectangle.Y,rectangle.Right,rectangle.Y);
                //handle 4
                tempPath.AddLine(rectangle.X,rectangle.Y+rectangle.Height/2,rectangle.X,rectangle.Y+rectangle.Height/2);
                //handle 5
                tempPath.AddLine(rectangle.Right,rectangle.Y+rectangle.Height/2,rectangle.Right,rectangle.Y+rectangle.Height/2);
                //handle 6
                tempPath.AddLine(rectangle.X,rectangle.Bottom,rectangle.X,rectangle.Bottom);
                //handle 7
                tempPath.AddLine(rectangle.X + rectangle.Width/2,rectangle.Bottom,rectangle.X + rectangle.Width/2,rectangle.Bottom);
                //handle 8
                tempPath.AddLine(rectangle.Right,rectangle.Bottom,rectangle.Right,rectangle.Bottom);
                tempPath.Transform(matrix);
    //根据中心点添加手柄显示矩形
                handlePath = new GraphicsPath();
                HandleList = new List<RectangleF>();
                HandleList.Add(RectangleZoom(new PointF(tempPath.PathPoints[0].X, tempPath.PathPoints[0].Y )));
                HandleList.Add(RectangleZoom(new PointF(tempPath.PathPoints[2].X , tempPath.PathPoints[2].Y)));
                HandleList.Add(RectangleZoom(new PointF(tempPath.PathPoints[4].X, tempPath.PathPoints[4].Y)));
                HandleList.Add(RectangleZoom(new PointF(tempPath.PathPoints[6].X, tempPath.PathPoints[6].Y)));
                HandleList.Add(RectangleZoom(new PointF(tempPath.PathPoints[8].X, tempPath.PathPoints[8].Y)));
                HandleList.Add(RectangleZoom(new PointF(tempPath.PathPoints[10].X, tempPath.PathPoints[10].Y)));
                HandleList.Add(RectangleZoom(new PointF(tempPath.PathPoints[12].X, tempPath.PathPoints[12].Y)));
                HandleList.Add(RectangleZoom(new PointF(tempPath.PathPoints[14].X, tempPath.PathPoints[14].Y)));
    //存放旋转后的中心点-际存放3,4个手柄的中心点就可以了
                HandleCenterPoint[0] = tempPath.PathPoints[0];
                HandleCenterPoint[1] = tempPath.PathPoints[2];
                HandleCenterPoint[2] = tempPath.PathPoints[4];
                HandleCenterPoint[3] = tempPath.PathPoints[6];
                HandleCenterPoint[4] = tempPath.PathPoints[8];
                HandleCenterPoint[5] = tempPath.PathPoints[10];
                HandleCenterPoint[6] = tempPath.PathPoints[12];
                HandleCenterPoint[7] = tempPath.PathPoints[14];
    //将手柄矩形添加到graphicpath中
                for (int i = 0; i < 8; i++)
                {
                    handlePath.AddRectangle(HandleList[i]);
                }            handlePath.FillMode = FillMode.Winding;
    //如要矩形大小改变,则重新计算中心点,及矩形的x,y的坐标
                RoatePoint = new PointF(HandleCenterPoint[3].X + (HandleCenterPoint[4].X - HandleCenterPoint[3].X) / 2, HandleCenterPoint[3].Y+(HandleCenterPoint[4].Y - HandleCenterPoint[3].Y) / 2);
                rectangle.X = RoatePoint.X - (float)rectangle.Width / 2;
                rectangle.Y = RoatePoint.Y - (float)rectangle.Height / 2;
            }