鼠标控制矩形旋转的方法

CLeehom 2016-06-24 11:23:12
在graphic中画一个矩形,想通过用鼠标的移动控制矩形绕指定点旋转,有没有什么好的方法
...全文
1289 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
desperaso 2017-12-28
  • 打赏
  • 举报
回复
demo 在https://pan.baidu.com/s/1mi5ntBM 代码在:https://pan.baidu.com/s/1slWNEdJ 图像运算在 3D_effect 文件夹内 原理是立方体的旋转,要改为鼠标控制,控制X,Y,Z三个位置和长度,立方体那个角度都可以转
一世情懷 2017-12-26
  • 打赏
  • 举报
回复 1
引用 9 楼 xuzuning 的回复:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace 鼠标旋转矩形
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            MouseDown += new MouseEventHandler(OnMouseDown);
            MouseMove += new MouseEventHandler(OnMouseMove);

            Text = "右键定点 左键拖拽";
        }
        int ox = -1;
        int oy = -1;
        int mx = 0;
        int my = 0;
        protected override void OnPaint(PaintEventArgs e)
        {          
            var g = e.Graphics;
            using (var path = new GraphicsPath())
            {
                path.AddRectangle(new Rectangle(30, 30, 230, 160));

                if (ox < 0 || oy < 0)
                {
                    g.DrawPath(Pens.Black, path);
                    return;
                }

                g.DrawLine(Pens.Red, ox - 5, oy, ox + 5, oy);
                g.DrawLine(Pens.Red, ox, oy - 5, ox, oy + 5);

                if (mx > 0 || my > 0)
                {
                    var a = Math.Atan2(my - oy, mx - ox);
                    var n1 = (float)Math.Cos(a);
                    var n2 = (float)Math.Sin(a);
                    var n3 = -(float)Math.Sin(a);
                    var n4 = (float)Math.Cos(a);
                    var n5 = (float)((ox * (1 - Math.Cos(a)) + oy * Math.Sin(a)));
                    var n6 = (float)((oy * (1 - Math.Cos(a)) - ox * Math.Sin(a)));
                    path.Transform(new Matrix(n1, n2, n3, n4, n5, n6));
                }
                g.DrawPath(Pens.Black, path);
            }
 
        }
        void OnMouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ox = e.X;
                oy = e.Y;
                mx = e.X;
                my = e.Y;
                Invalidate();
            }
        }
        void OnMouseMove(object sender, MouseEventArgs e)
        {            
            if (e.Button == MouseButtons.Left)
            {
                mx = e.X;
                my = e.Y;
                Invalidate();
            }
        }
    }
}
版本威武,有c++在mfc下的demo作参考么?
xuzuning 2016-06-25
  • 打赏
  • 举报
回复
引用 12 楼 qq_32182351 的回复:
像这样如果多个矩形填充不同的颜色能实现吗
有区别吗? 虽然 GraphicsPath 是单色的(轮廓与充填色可以不同),但你可以将复杂的多色图形分解成若干个单色图形逐个绘制 任何工具都只是辅助你达成目标,而不能替你完成创意
CLeehom 2016-06-24
  • 打赏
  • 举报
回复
还有怎么判断鼠标是顺时针还是逆时针移动?
CLeehom 2016-06-24
  • 打赏
  • 举报
回复
引用 4 楼 wjkaola123 的回复:
确定矩形的中心点与鼠标点连成一条直线,鼠标移动产生的角度,也是矩形左上角和右下角需要同方向转动的角度,计算出这两个点的坐标位置, 对图形进行重绘
求出了角度,怎么进行重绘?我试过用Graphic.TranslateTransform和Graphic.RotateTransform,但我的原点是要沿着圆弧移动的,用Graphic.TranslateTransform可以吗?还有Graphic.RotateTransform是顺时针还是逆时针旋转的?
  • 打赏
  • 举报
回复
资助 --> 自主 从你这只有一句话的简单描述看,其实你一开始陷入了非常底层的思路中,然后不切实际地去想学人家搞点高层的设计。我帮你把需求设计层次再提高一点,帮你早一点认清哪些技术不应该学。
  • 打赏
  • 举报
回复
你应该先测试在画布上有用户资助添加任意n个矩形,然后用户可以拖动矩形(包括跃过另外一个矩形)。只有这之后,你再来测试、开发“拖动旋转某一个矩形”。这时候你采用的技术才会真正是最终你要采用的技术。 如果从底层开始“玩儿”,你学的一堆东西可能很快都要放弃。因为底层的那些东西在设计层次升高时技术变化很大,80%都是错误的编程思路。
wjkaola123 2016-06-24
  • 打赏
  • 举报
回复
确定矩形的中心点与鼠标点连成一条直线,鼠标移动产生的角度,也是矩形左上角和右下角需要同方向转动的角度,计算出这两个点的坐标位置, 对图形进行重绘
巴士上的邂逅 2016-06-24
  • 打赏
  • 举报
回复
固定了矩形大小,再根据第一个固定点与鼠标的角度,来调整矩形角度
巴士上的邂逅 2016-06-24
  • 打赏
  • 举报
回复
矩形旋转,矩形长宽会变吗? 你的意思应该是大小不变只是角度变化,应该还有一个点,固定矩形大小
xdashewan 2016-06-24
  • 打赏
  • 举报
回复
计算鼠标与点的角度,根据角度画矩形
龍过鸡年 2016-06-24
  • 打赏
  • 举报
回复
建议你使用 wpf 做这个工作,原因有几点: 第一,控件的布局处理 该控件内部的图形旋转时,由于角度问题,绘制图形的区域会大于控件实际尺寸,此时控件大小是否需要自动调整?以哪一点为参照进行调整,比如左上角,中心点? 第二,控件的背景色与图形的背景色处理 当控件中的图形旋转后,控件的背景色和图形的背景色需要分别绘制。而且控件的背景色是无法做到透明的,实际是利用了 Parent 的背景色,让控件看起来透明而已。如果有多个类似控件需要叠加时,就会很难协调。 第三,控件的鼠标事件与图形的鼠标事件如何处理 响应鼠标事件时,需要区分鼠标落点已实现正确的处理。 wpf 中,提供了 canvas 画布,控件也是现成的,可以通过 path 组合成各种图形,还是矢量的。 控件都有 rendertransform 变形处理,放大缩小,旋转,都很方便。而且还提供有3d对象和场景的处理及变换。 控件还有 ishittestvisible 可设置控件是否响应鼠标事件,ismousecaptured 可以判断控件是否捕获了鼠标。 对于色彩的处理也相当方便。 假如,你一定要在winform 中实现,那你可能做个画布控件更好,然后做类似 ps 中的各种图形对象,在画布上通过鼠标绘制图形对象,记录其位置、大小,背景色、边框样式、旋转角度、图形的形状等等,还需要处理图形的拖拽、缩放、旋转。
CLeehom 2016-06-24
  • 打赏
  • 举报
回复

像这样如果多个矩形填充不同的颜色能实现吗

xuzuning 2016-06-24
  • 打赏
  • 举报
回复
g.DrawPath 是画轮廓 g.FillPath 不就是充填了吗 使用 path 的目的是将仿射矩阵限制在小范围,从而减少计算量,也可防止操作失误 在 Graphics 上也是可以可以使用仿射矩阵的 Graphic.TranslateTransform、Graphic.RotateTransform 实际上都是通过仿射矩阵实现的
CLeehom 2016-06-24
  • 打赏
  • 举报
回复
引用 9 楼 xuzuning 的回复:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace 鼠标旋转矩形
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            MouseDown += new MouseEventHandler(OnMouseDown);
            MouseMove += new MouseEventHandler(OnMouseMove);

            Text = "右键定点 左键拖拽";
        }
        int ox = -1;
        int oy = -1;
        int mx = 0;
        int my = 0;
        protected override void OnPaint(PaintEventArgs e)
        {          
            var g = e.Graphics;
            using (var path = new GraphicsPath())
            {
                path.AddRectangle(new Rectangle(30, 30, 230, 160));

                if (ox < 0 || oy < 0)
                {
                    g.DrawPath(Pens.Black, path);
                    return;
                }

                g.DrawLine(Pens.Red, ox - 5, oy, ox + 5, oy);
                g.DrawLine(Pens.Red, ox, oy - 5, ox, oy + 5);

                if (mx > 0 || my > 0)
                {
                    var a = Math.Atan2(my - oy, mx - ox);
                    var n1 = (float)Math.Cos(a);
                    var n2 = (float)Math.Sin(a);
                    var n3 = -(float)Math.Sin(a);
                    var n4 = (float)Math.Cos(a);
                    var n5 = (float)((ox * (1 - Math.Cos(a)) + oy * Math.Sin(a)));
                    var n6 = (float)((oy * (1 - Math.Cos(a)) - ox * Math.Sin(a)));
                    path.Transform(new Matrix(n1, n2, n3, n4, n5, n6));
                }
                g.DrawPath(Pens.Black, path);
            }
 
        }
        void OnMouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ox = e.X;
                oy = e.Y;
                mx = e.X;
                my = e.Y;
                Invalidate();
            }
        }
        void OnMouseMove(object sender, MouseEventArgs e)
        {            
            if (e.Button == MouseButtons.Left)
            {
                mx = e.X;
                my = e.Y;
                Invalidate();
            }
        }
    }
}
如果是有填充的矩形呢,怎么在画出来的矩形中填充?还能能不能获取画出来的GraphicsPath中的矩形对象?
xuzuning 2016-06-24
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace 鼠标旋转矩形
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MouseDown += new MouseEventHandler(OnMouseDown);
MouseMove += new MouseEventHandler(OnMouseMove);

Text = "右键定点 左键拖拽";
}
int ox = -1;
int oy = -1;
int mx = 0;
int my = 0;
protected override void OnPaint(PaintEventArgs e)
{
var g = e.Graphics;
using (var path = new GraphicsPath())
{
path.AddRectangle(new Rectangle(30, 30, 230, 160));

if (ox < 0 || oy < 0)
{
g.DrawPath(Pens.Black, path);
return;
}

g.DrawLine(Pens.Red, ox - 5, oy, ox + 5, oy);
g.DrawLine(Pens.Red, ox, oy - 5, ox, oy + 5);

if (mx > 0 || my > 0)
{
var a = Math.Atan2(my - oy, mx - ox);
var n1 = (float)Math.Cos(a);
var n2 = (float)Math.Sin(a);
var n3 = -(float)Math.Sin(a);
var n4 = (float)Math.Cos(a);
var n5 = (float)((ox * (1 - Math.Cos(a)) + oy * Math.Sin(a)));
var n6 = (float)((oy * (1 - Math.Cos(a)) - ox * Math.Sin(a)));
path.Transform(new Matrix(n1, n2, n3, n4, n5, n6));
}
g.DrawPath(Pens.Black, path);
}

}
void OnMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ox = e.X;
oy = e.Y;
mx = e.X;
my = e.Y;
Invalidate();
}
}
void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mx = e.X;
my = e.Y;
Invalidate();
}
}
}
}

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧