C# 需要建议-如何编写绘图程序
我想写一个程序,使用户能够绘制诸如圆、三角形、矩形等几何形状 我还希望能够拖放或调整/移动以前绘制的形状C# 需要建议-如何编写绘图程序,c#,gdi+,C#,Gdi+,我想写一个程序,使用户能够绘制诸如圆、三角形、矩形等几何形状 我还希望能够拖放或调整/移动以前绘制的形状 我想画一个面板里面的形状。这似乎合理吗 在我画了一个圆之后,它就变成了位图的一部分。当然,我会将圆的细节保存在其他对象中 但我不明白的是如何实现以下内容: 当鼠标位于圆上方时,选择圆,然后使用某个键可使用户调整/移动圆的大小 我怎么知道鼠标在圆圈上方 是否需要检查鼠标坐标与所有圆形像素坐标 我在寻找更简单的解决方案 使用WPF图形和多媒体 Windows演示基金会(WPF)包括支持高质量的
我在寻找更简单的解决方案 使用WPF图形和多媒体
Windows演示基金会(WPF)包括支持高质量的二维和三维图形、动画和媒体。图形平台的主要功能包括:
矢量图形支持 硬件加速 分辨率和设备无关的图形 最小屏幕重画和集成动画系统 它拥有你所需要的一切——为什么要重新发明轮子 您需要将对象本身保持为图形对象,以便它们能够响应鼠标悬停事件。一旦你把它们放到位图中,你就必须重新发明轮子 比如说, 以下是形状对象: 以下是命中测试:您还可以利用硬件加速、分辨率和与设备无关的图形。我认为您自己无法轻松实现此功能:)您必须使用自定义控件并在此基础上绘制任何内容。每个形状都是具有某些属性的对象。创建一个名为
IShape
的接口,然后创建几个实现它的类,例如Rectangle
和Circle
。当用户单击屏幕时,您必须按每个对象位置比较光标位置,然后执行某些操作并使屏幕无效。您应该使用绘制事件在自定义双缓冲控件内绘制形状
例如:
///<summary>A blank control for drawing on.</summary>
[DefaultEvent("Paint")]
[Description("A blank control for drawing on.")]
[ToolboxBitmap(typeof(Canvas), "Images.Canvas.png")]
public class Canvas : Control {
///<summary>Creates a new Canvas control.</summary>
public Canvas() {
SetStyle(ControlStyles.AllPaintingInWmPaint
| ControlStyles.UserPaint
| ControlStyles.Opaque
| ControlStyles.OptimizedDoubleBuffer
| ControlStyles.ResizeRedraw,
true);
}
///<summary>Gets or sets whether the control should completely repaint when it is resized.</summary>
[Description("Gets or sets whether the control should completely repaint when it is resized.")]
[DefaultValue(true)]
[Category("Appearance")]
public new bool ResizeRedraw {
get { return base.ResizeRedraw; }
set { base.ResizeRedraw = value; }
}
///<summary>Raises the Paint event.</summary>
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "CA Bug")]
protected override void OnPaint(PaintEventArgs e) {
if (e == null) throw new ArgumentNullException("e");
if (ShowDesignMessage && DesignMode) {
using (var brush = new LinearGradientBrush(ClientRectangle, Color.AliceBlue, Color.DodgerBlue, LinearGradientMode.Vertical)) {
e.Graphics.FillRectangle(brush, ClientRectangle);
}
using (var font = new Font("Segoe UI", 18))
using (var format = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }) {
e.Graphics.DrawString("Canvas Control", font, Brushes.DarkBlue, ClientRectangle, format);
}
} else
base.OnPaint(e);
}
///<summary>Gets whether to paint a message in design mode instead of firing the Paint event.</summary>
[Browsable(false)]
protected virtual bool ShowDesignMessage { get { return true; } }
}
///用于在其上绘图的空白控件。
[默认事件(“绘制”)]
[说明(“用于绘图的空白控件”)]
[ToolboxBitmap(typeof(Canvas),“Images.Canvas.png”)]
公共类画布:控件{
///创建一个新的画布控件。
公共画布(){
设置样式(ControlStyles.AllPaintingInWmPaint
|ControlStyles.UserPaint
|控件样式。不透明
|ControlStyles.OptimizedDubleBuffer
|ControlStyles.ResizerDraw,
正确的);
}
///获取或设置控件调整大小时是否应完全重新绘制。
[说明(“获取或设置控件调整大小时是否应完全重新绘制。”)]
[默认值(真)]
[类别(“外观”)]
公共新布尔ResizeRedraw{
获取{return base.ResizeRedraw;}
设置{base.ResizeRedraw=value;}
}
///引发绘制事件。
[SuppressMessage(“Microsoft.Reliability”,“CA2000:在失去作用域之前处理对象”,justify=“CA Bug”)]
受保护的覆盖无效OnPaint(PaintEventArgs e){
如果(e==null)抛出新的ArgumentNullException(“e”);
if(显示设计消息和设计模式){
使用(var笔刷=新的LinearGradientBrush(ClientRectangle、Color.AliceBlue、Color.DodgerBlue、LinearGradientMode.Vertical)){
e、 图形。填充矩形(画笔、ClientRectangle);
}
使用(var字体=新字体(“Segoe UI”,18))
使用(var format=new StringFormat{Alignment=StringAlignment.Center,LineAlignment=StringAlignment.Center}){
e、 Graphics.DrawString(“画布控件”、字体、画笔、深蓝色、ClientRectangle、格式);
}
}否则
基础漆(e);
}
///获取是否在设计模式下绘制消息,而不是触发绘制事件。
[可浏览(错误)]
受保护的虚拟bool ShowDesignMessage{get{return true;}}
}
您应该处理画布的绘制事件,并使用e.Graphics
绘制所有形状对象
在鼠标事件中,您需要遍历所有形状并找到包含鼠标的最后一个形状。要检查圆是否包含鼠标,请使用毕达哥拉斯定理获得鼠标与圆中心之间的距离。假设有两个三角形,如下所示: 要表示图片,可以将其存储在列表中:
var picture = new List<Triangle> { red, blue };
为了让用户修改图片,您可以检测鼠标左键按下的坐标。然后,按顺序枚举列表,并检查三角形的最近角
foreach (var triangle in picture)
{
DrawTriangle(graphics, triangle);
}
foreach (var triangle in picture.Reverse())
{
for (int i = 0; i < 3; i++)
{
if (Distance(mouse, triangle.Corner[i]) < 5)
{
// drag corner until mouse is released
return;
}
}
}
foreach(picture.Reverse()中的变量三角形)
{
对于(int i=0;i<3;i++)
{
if(距离(鼠标、三角形、角[i])<5)
{
//拖动角点直到释放鼠标
返回;
}
}
}
在Office、Visio、PaintShop和所有绘图软件包中,您都有Z顺序的概念
你也需要这样的东西。我想知道如果你有撤销缓冲区,你是否会有大量的磁盘分页。需要考虑的事情。< /P>
撤消缓冲区很重要。除非你不想有撤销功能。也许你可以保存矢量数据,也许是位图
此外,在正在绘制的对象下的缓冲区,图形卡仅在UI上(而不是在内存中)进行矢量运算的速度非常快。取决于您要查找的内容、需要处理的内容、需要多少(图形)对象。双重缓冲可能是好的,也可能是坏的
对于循环命中测试:-
isInCircle = (((cursorx-circlecentrex)*(cursorx-circlecentrex)+
(cursory-circlecentrey)*(cursory-circlecentrey)) < circleradius)
isInCircle=((光标x圆中心)*(光标x圆中心)+
(粗略的保监会
isInCircle = (((cursorx-circlecentrex)*(cursorx-circlecentrex)+
(cursory-circlecentrey)*(cursory-circlecentrey)) < circleradius)