19.1 规则和活动交点的平滑移动
在之前的版本中,规则和活动的关联,如果活动图形是矩形或者菱形,那么系统只定义了4个关联点,分别在上下左右,如下图所示:
这样的关联设定也可以用,但还不是很完美,经过改进,现在实现为两个活动的中间连线与活动的相交点。如果拖动活动或者规则,那么这个交点就会平滑的移动,不会像之前那样在4个点之间跳动了,如下图所示:
这个功能的实现不复杂,主要是分析好各种关系就可以了。下面以矩形图活动为例,具体描述一下相应的思路和代码。如下图所示:
现在已知起始点坐标与终点坐表,以及活动A的长和宽,求从起始点到终点的连线和活动A的交点。这是一个很简单的平面几何算数题,我们需要注意的是当起始点坐标和终点坐表的相对位置不同时(例如,起始点在终点的左上、左下、右上、右下),计算公式稍有变化。下面的代码具体描述了计算方法。
Code
//起始点坐标和终点坐标之间的夹角(相对于Y轴坐标系)
double angle = Math.Abs(Math.Atan((endPoint.X - beginPoint.X) / (endPoint.Y - beginPoint.Y)) * 180.0 / Math.PI);
//活动的长和宽之间的夹角(相对于Y轴坐标系)
double angel2 =Math.Abs( Math.Atan(PictureWidth / PictureHeight) * 180.0 / Math.PI);
//半径
double radio = PictureHeight<PictureWidth?PictureHeight/2:PictureWidth/2;
if (angle <= angel2)//起始点坐标在终点坐标的上方,或者下方
{
if (endPoint.Y < beginPoint.Y)//在上方
{
if (endPoint.X < beginPoint.X)
p.X = endPoint.X + Math.Tan(Math.PI * angle / 180.0) * radio;
else
p.X = endPoint.X - Math.Tan(Math.PI * angle / 180.0) * radio;
p.Y = endPoint.Y + PictureHeight / 2;
}
else//在下方
{
if (endPoint.X < beginPoint.X)
p.X = endPoint.X + Math.Tan(Math.PI * angle / 180.0) * radio;
else
p.X = endPoint.X - Math.Tan(Math.PI * angle / 180.0) * radio;
p.Y = endPoint.Y - PictureHeight / 2;
}
}
else//左方或者右方
{
if (endPoint.X < beginPoint.X)//在右方
{
p.X = endPoint.X + PictureWidth / 2;
if (endPoint.Y < beginPoint.Y)
p.Y = endPoint.Y + Math.Tan(Math.PI * (90 - angle) / 180.0) * radio;
else
p.Y = endPoint.Y - Math.Tan(Math.PI * (90 - angle) / 180.0) * radio;
}
else//在左方
{
p.X = endPoint.X - PictureWidth / 2;
if (endPoint.Y < beginPoint.Y)
p.Y = endPoint.Y + Math.Tan(Math.PI * (90 - angle) / 180.0) * radio;
else
p.Y = endPoint.Y - Math.Tan(Math.PI * (90 - angle) / 180.0) * radio;
}
19.2 双击面板生成活动
这个功能也是网友的建议,现在生成活动可以使用两种方式,点击添加活动 按钮,以及使用右键菜单。根据网友建议,增加一个新的方式,双击容器面板,在当前位置生成活动。这个功能比较简单,主要是检测鼠标双击事件,然后在当前鼠标位置生成一个活动,具体的代码如下:
Activity a = new Activity((IContainer)this, ActivityType.INTERACTION);
a.ActivityName = Text.NewActivity + NextNewActivityIndex.ToString();
Point p = e.GetPosition(this);
a.CenterPoint = new Point(p.X - this.Left, p.Y - this.Top);
this.AddActivity(a);