📄 cline.cs
字号:
using System;
using System.Drawing;
namespace VCSharp
{
/// <summary>
/// CLine 的摘要说明。
/// </summary>
///
//直线段类
[Serializable()]public class CLine:CGElement
{
protected PointF m_Begin;
protected PointF m_End;
Module m=new Module();
public PointF LBegin
{
get{return m_Begin;}
set{m_Begin=value;}
}
public PointF LEnd
{
get{return m_End;}
set{m_End=value;}
}
public CLine()
{
Init();
}
public CLine(PointF pBegin,PointF pEnd)
{
Init();
m_Begin=pBegin;
m_End=pEnd;
}
public CLine(CLine aline)
{
m_Begin=aline.LBegin;
m_End=aline.LEnd;
}
private new void Init()
{
base.Init();
m_Begin=new PointF(0,0);
m_End=new PointF(0,0);
}
//绘直线段
override public void Draw(Graphics g,DrawMode aDrawMode)
{
long aPen,oldP;
//将控制点的坐标由世界坐标转换为页面坐标
PointF eb=m.WorldtoPage(m_Begin);
PointF ee=m.WorldtoPage(m_End);
//获得当前绘图环境的句柄
IntPtr hdc=g.GetHdc();
//设置画笔参数
int[] penPara=DrawSettings(hdc,aDrawMode);
//创建画笔
aPen=Win32API.CreatePen(penPara[0],penPara[1],penPara[2]);
//把画笔选入绘图环境,并返回原来的画笔
oldP=Win32API.SelectObject(hdc,aPen);
Win32API.LPPOINT prePos=new Win32API.LPPOINT();
//把画笔移动到直线段的起点处
Win32API.MoveToEx(hdc, (int)(eb.X), (int)(eb.Y), prePos);
//绘直线段到终点
Win32API.LineTo(hdc, (int)(ee.X), (int)(ee.Y));
//把原来的画笔选入绘图环境
Win32API.SelectObject(hdc, oldP);
//删除新创建的画笔
Win32API.DeleteObject(aPen);
//释放绘图环境句柄
g.ReleaseHdc(hdc);
}
//计算包围矩形
override public CBox GetBox()
{
CBox aBox=new CBox();
if (m_Begin.X==m_End.X)
{
aBox.minX=m_Begin.X-Const.PickRadius;
aBox.minY=Math.Min(m_Begin.Y,m_End.Y);
aBox.maxX=m_Begin.X+Const.PickRadius;
aBox.maxY=Math.Max(m_Begin.Y,m_End.Y);
}
else if (m_Begin.Y==m_End.Y)
{
aBox.minX=Math.Min(m_Begin.X,m_End.X);
aBox.minY=m_Begin.Y-Const.PickRadius;
aBox.maxX=Math.Max(m_Begin.X,m_End.X);
aBox.maxY=m_Begin.Y+Const.PickRadius;
}
else
{
aBox.minX=Math.Min(m_Begin.X,m_End.X);
aBox.minY=Math.Min(m_Begin.Y,m_End.Y);
aBox.maxX=Math.Max(m_Begin.X,m_End.X);
aBox.maxY=Math.Max(m_Begin.Y,m_End.Y);
}
return aBox;
}
//计算点到直线段的距离
private float distPtoL(PointF aPos,CLine aLine)
{
float px,py,dist;
float distX,distY;
float[] kc;
px=aPos.X;
py=aPos.Y;
//获取直线段的截距式方程,返回斜率和截距
kc=aLine.LineKX();
//如果为水平直线段
if (kc[0]==0)
{
distX=10000;
distY=Math.Abs(py-aLine.LBegin.Y);
}
//如果为竖直直线段
else if (kc[0]==10000)
{
distX=Math.Abs(px-aLine.LBegin.X);
distY=10000;
}
//如果为斜线
else
{
distX=Math.Abs(px-(py-kc[1])/kc[0]);
distY=Math.Abs(py-(kc[0]*px+kc[1]));
}
//返回水平距离和竖直距离之间的小值
dist=Math.Min(distX,distY);
return dist;
}
//计算直线段的截距式方程
private float[] LineKX()
{
float kc0,kc1;
//若直线段不为竖直线段
if (m_Begin.X!=m_End.X)
{
kc0=(m_End.Y-m_Begin.Y)/(m_End.X-m_Begin.X);
}
//如果是竖直线段
else
{
kc0=10000f;
}
//计算截距
kc1=m_Begin.Y-kc0*m_Begin.X;
float[] kc={kc0,kc1};
return kc;
}
//拾取直线段
override public bool Pick(PointF aPos)
{
CBox geBox=new CBox();
//判断拾取点是否在测试包围矩形中,若不是,
//则直线段不被拾取
if (!(m.InBox(GetBox(),aPos)))
{
return false;
}
else
{
if (distPtoL(aPos,this)<Const.PickRadius)
{
return true;
}
else
{
return false;
}
}
}
//判断拾取点是否位于包围矩形中
private bool InBox(CBox aBox,PointF aPos)
{
if (aPos.X>aBox.minX && aPos.Y>aBox.minY
&& aPos.X<aBox.maxX && aPos.Y<aBox.maxY)
{
return true;
}
else
{
return false;
}
}
//平移变换
override public void Move(Graphics g,PointF basePos,PointF desPos)
{
float xx,yy;
//计算在X和Y两个方向上的位移量
xx = desPos.X - basePos.X;
yy = desPos.Y - basePos.Y;
m_Begin.X += xx;
m_Begin.Y += yy;
m_End.X += xx;
m_End.Y += yy;
}
//旋转变换
override public void Rotate(Graphics g,PointF basePos, float aAngle)
{
m_Begin = m.pRotate(basePos, m_Begin, aAngle);
m_End = m.pRotate(basePos, m_End, aAngle);
}
//镜像变换
override public void Mirror(Graphics g,PointF pPos1,PointF pPos2)
{
m_Begin = m.pMirror(pPos1, pPos2, m_Begin);
m_End = m.pMirror(pPos1, pPos2, m_End);
}
//比例变换
override public void Scale(Graphics g, float sx,float sy)
{
m_Begin.X *=sx;
m_Begin.Y *= sy;
m_End.X *= sx;
m_End.Y *=sy;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -