C# GDI+ 画图问题 高分请教

ttiimm11 2010-10-28 02:38:14
参考网上的代码,我要画一个线段和一个与之平行的虚线段,像这样的

——————
- - - - - -

我的代码如下:

protected override void GeneratePath()
{
bool isLine = true;

_Path = new System.Drawing.Drawing2D.GraphicsPath();
_Path.AddLine(Location.X + Size.Width, Location.Y, Location.X + Size.Width, Location.Y + Size.Height);

_Path.CloseAllFigures();
_Path.AddLine(Location.X, Location.Y, Location.X, Location.Y + Size.Height);

for (int i = Location.Y; i < Location.Y + Size.Height; i = i + 2)
{
if (isLine)
{
int st = i;
int ed = st + 2;
if (st + 2 <= Location.Y + Size.Height)
{
_Path.CloseFigure();
Point pStart = new Point(Location.X, st);
Point pEnd = new Point(Location.X, ed);
_Path.AddLine(pStart, pEnd);
_Path.CloseFigure();
isLine = false;
}
}
else
{
isLine = true;
}

}
InvalidationArea = Rectangle.Round(_Path.GetBounds());
}


我想实现等鼠标点击线段和虚线段区域之间的点时,移动图像

if (Path.IsVisible(e.Location))
return true;

问题是,当我点击区域之间的点是,上面的这个函数返回的是False。如何才能选中并移动呢???

其他代码

public virtual bool HitTest(MouseEventArgs e)
{
//we only need the Location of the mouse but by passing
//the MouseEventArgs, no value copying has to occur.
//Only the memory reference will be passed

if (isSelected && InvalidationArea.Contains(e.Location))
return true;
else if (Path.IsVisible(e.Location))
return true;

return false;
}

public virtual EventData MouseDown(MouseEventArgs e)
{
eventData.WasHit = HitTest(e);

if (eventData.WasHit)
{
isSelected = true;
if (!(editingOn && !painter.State.AcceptsEditing))
{
mouseOffset = new PointF(Path.GetBounds().X - e.X, Path.GetBounds().Y - e.Y);
pntMoveStartPos = Point.Round(Path.GetBounds().Location);
pntBitmapPos = pntMoveStartPos;
rectOldBounds = GetShapeBounds(false);
mouseIsPressed = true;
isResizing = (ResizeHandles.HitTest(e.Location));

}
eventData.NeedsPainted = true;
}
else if (isSelected)
{
isSelected = false;
painter.State.IsSelected = false;
eventData.NeedsPainted = true;
}
return eventData;
}
public virtual bool MouseMove(MouseEventArgs e)
{
if (isSelected && !editingOn && !mouseIsPressed)
{
ResizeHandles.HitTest(e.Location);
}
doOperation = false;
if (mouseIsPressed)
{
eventData.NeedsPainted = true;
if (isResizing)
{
Rectangle oldBounds = ResizeHandles.Bounds;//InvalidationArea;
Resize(e.Location);
blnSuppressInflate = true;
InvalidationArea = Rectangle.Union(oldBounds,
GetShapeBounds(false));
blnSuppressInflate = false;
doOperation = true;
}
else
{
if (bmpMove == null)
{
RectangleF rectBounds = Path.GetBounds();
Point tmpLocation = Point.Round(rectBounds.Location);
Size tmpSize = Size.Round(rectBounds.Size);
GeneratePath(new Rectangle(0, 0, (int)rectBounds.Width, (int)rectBounds.Height));

bmpMove = new Bitmap((int)rectBounds.Width+2, (int)rectBounds.Height+2);
Graphics g = Graphics.FromImage(bmpMove);
bool blnTemp = painter.PaintFill;
painter.PaintFill = false;
painter.Paint(g, Path);
painter.PaintFill = blnTemp;
g.Dispose(); g = null;

Location = tmpLocation;
Size = tmpSize;
_Path = null;
//sbLog.Append("Init and Paint the drag bitmap...\r\n");
}


Rectangle oldBounds = new Rectangle(pntBitmapPos, bmpMove.Size);

pntBitmapPos = new Point((int)(e.X + mouseOffset.X), (int)(e.Y + mouseOffset.Y));
InvalidationArea = Rectangle.Union(oldBounds,
new Rectangle(pntBitmapPos, bmpMove.Size));
doOperation = true;
// sbLog.Append("BitmapPos: " + pntBitmapPos.X + "," + pntBitmapPos.Y + "; Invalidation: " + _InvalidationArea.ToString() + "\r\n");
}
}
return doOperation;
}

...全文
255 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
lazygank 2010-11-02
  • 打赏
  • 举报
回复
MouseDown事件,需确定按下的位置是否是在你说描绘的区域中,设置参数,斜率什么用数学算一下,点到直线的距离等都可能用到.

/// <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;
}

这个是移动一条直线的时候判断点的位置.
deyygywxf 2010-10-29
  • 打赏
  • 举报
回复
啥复杂的吧。直接平移起点后按原来坐标重新绘制一条直线不就可以了?只要不旋转,必然平行。网上代码写复杂了。
HaveOneDream 2010-10-29
  • 打赏
  • 举报
回复
一样,我也是一个人,项目也应用到GDI+,前段时间刚学,项目基本功能也实现了,有机会可以交流一下,互相学习,共同进步
CraxyMouse 2010-10-28
  • 打赏
  • 举报
回复
我之前写的一个(广告中的E-Label就是基本这个升级的):
http://blog.csdn.net/dunao/archive/2009/02/05/3865053.aspx

插播广告:)

E-Label是一个专业条码标签打印软件.它会让条码标签打印变得更简单.更方便二次开发(.NET)

目前此软件在Beta阶段.如果你对些软件有兴趣可以到

http://www.ync-tech.com下截Beta版本

兔子-顾问 2010-10-28
  • 打赏
  • 举报
回复
粘贴如下代码在你窗体的按钮中。点击看效果。

using (Graphics g = this.CreateGraphics())
{
g.DrawLine(Pens.Black, 75, 100, 125, 290);
//x平移50个像素,y上平移30个像素
GraphicsContainer c = g.BeginContainer(new Rectangle(50, -30, Width, Height), new Rectangle(0, 0, Width, Height), GraphicsUnit.Pixel);
Pen p = new Pen(Color.DarkGray);
p.DashStyle = DashStyle.DashDot;
g.DrawLine(p, 75, 100, 125, 290);//基准点已经偏移,你可以按原来坐标再次绘制。就得到平移后的线了。
p.Dispose();
g.EndContainer(c);
}


你可以下载我资源中的这个例子,gdi+绘图的,非常全面。
http://download.csdn.net/source/2090762
ttiimm11 2010-10-28
  • 打赏
  • 举报
回复

if (InvalidationArea.Contains(e.Location))
return true;


我这样写了,现在没看出来有什么不对的地方,至少可选中,可移动了,但不可旋转,我也用不到旋转。
谢谢wuyazhe,又是你,还是那个项目,按照你说的,现在正在一步步的慢慢学习GDI+,有了点心得。项目也在进行着,还是我一个人,但有希望了。
兔子-顾问 2010-10-28
  • 打赏
  • 举报
回复
没啥复杂的吧。直接平移起点后按原来坐标重新绘制一条直线不就可以了?只要不旋转,必然平行。网上代码写复杂了。
porschev 2010-10-28
  • 打赏
  • 举报
回复
帮顶。。。不会。。。
ttiimm11 2010-10-28
  • 打赏
  • 举报
回复
如果我不用 _Path.CloseFigure() 且画的线是封闭图形,比如矩形,三角形,圆就不存在问题了。就算不封闭像 |_|的也可以。
内容概要:本文围绕不确定环境下的多式联运路径优化问题展开研究,提出并实现了基于AFO算法、遗传算法(GA)和粒子群优化算法(PSO)的三种智能优化方法,并借助Matlab平台完成算法编程与仿真。研究构建了考虑时间、成本、转运风险等多重不确定因素的路径优化模型,系统比较了AFO、GA、PSO三种算法在收敛速度、全局寻优能力和稳定性方面的表现,同时引入Matlab自带的全局优化搜索器作为基准对照,深入分析各算法在复杂物流网络中的适用边界与性能差异。研究表明,AFO算法在解决此类组合优化问题时展现出更快的收敛效率和更强的局部规避能力。; 适合人群:具备一定Matlab编程基础与运筹优化知识,从事物流工程、交通运输规划、智能算法开发等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多式联运、综合货运网络中的路径决策支持系统构建;②为不确定性条件下复杂路径规划问题提供智能算法选型依据与技术实现方案;③支持科研人员复现主流优化算法并开展横向性能对比实验,推动算法改进与实际落地。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点理解目标函数设计、约束条件处理及参数敏感性分析部分,可通过调整问题规模与算法参数进行对比实验,进一步拓展至动态路径规划或大规模网络优化等延伸场景。
内容概要:本文研究了基于QLearning自适应强化学习的PID控制器在自主水下航行器(AUV)运动控制中的应用,通过Matlab代码实现了控制算法的仿真验证。该方法融合强化学习的在线自适应能力与传统PID控制的稳定性优势,利用QLearning算法动态优化PID控制器的比例、积分、微分参数,以应对水下复杂流体环境、模型不确定性及外部干扰等挑战,从而提升AUV轨迹跟踪的精度、鲁棒性与动态响应性能。文中系统阐述了AUV的六自由度非线性动力学建模过程、QLearning算法的状态空间与动作空间设计、奖励函数构造及训练机制,并详细说明了PID参数自整定的闭环控制架构。仿真结果表明,相较于传统固定参数PID控制器,该智能控制策略在多种工况下均展现出更优的控制效果,有效抑制了超调,加快了响应速度,并增强了抗干扰能力。; 适合人群:具备自动控制理论、强化学习基础及Matlab/Simulink仿真能力,从事水下机器人、智能控制、海洋工程、自动化等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于AUV、UUV等无人水下平台的高精度自主导航与运动控制;②为解决非线性、强耦合、时变系统的控制器参数自适应整定问题提供智能化解决方案;③作为强化学习与经典控制理论深度融合的技术范例,推动智能控制算法在海洋装备中的工程化应用。; 阅读建议:建议读者结合提供的Matlab代码深入理解算法实现细节,重点剖析QLearning的状态-动作-奖励机制设计、PID参数更新逻辑及仿真对比实验结果,有条件者可在更复杂的动力学模型或实际硬件平台上进一步验证与优化算法性能。

111,129

社区成员

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

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

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