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

...全文
177 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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() 且画的线是封闭图形,比如矩形,三角形,圆就不存在问题了。就算不封闭像 |_|的也可以。

111,093

社区成员

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

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

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