1. 角平分线定义:
-
从一个角的顶点引出一条射线(线在角内),把这个角分成两个完全相同的角,这条射线叫做这个角的角平分线(bisectorof angle)。
-
角平分线是在角的型内及形上,到角两边距离相等的点的轨迹。(具体如附图)
2. 在VisionPro中创建角平分线
-
VisionPro中软件中没有提供封装好的角平分线工具,下面我 们介绍一种方法通过Vpro脚本实现角平分线的创建。
2. 求角平分线的脚本Angular bisector
3. 角平分线计算的理和过程
-
输入图像和直线A,B
-
把直线A,B的坐标空间映射到输入图像Image中,创建两条新 lineAMapped和lineBMapped
-
获取直线lineAMapped和直线lineAMapped上的参考点A(xA,yA,rA)和B(xB,yB,rB),这里的角度为指向相对于坐标系X轴的角度。
-
求取两条直线之间的角度β
-
计算两条直线平分线的角度MidAngle,这里需要判断是否为锐角
-
过两条直线上参考点的中心点建立一条垂直与角平分线的直线Cutline
-
分别求Cutline与lineAMapped的交点,以及Cutline与lineBMapped的交点,两个交点的中点设置为角平分线的参考点。
-
输出角平分线和对应角度(将弧度转换为角度)
-
运行效果如图
4. VisionPro脚本参考代码:
public override bool GroupRun(ref string message, ref CogToolResultConstants result)
{
// To let the execution stop in this script when a debugger is attached, uncomment the following lines.
// #if DEBUG
// if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
// #endif
///定义输入图像和初始化输出信号
CogImage8Grey image = mToolBlock.Inputs["Image"].Value as CogImage8Grey;
mToolBlock.Outputs["MidLine"].Value = null;
mToolBlock.Outputs["MidLineAngle"].Value = 999.999;
///定义lineA和lineB两条直线,并把输入的直线赋值给图像
// Run each tool using the RunTool function
foreach(ICogTool tool in mToolBlock.Tools)
mToolBlock.RunTool(tool, ref message, ref result);
CogLine lineA = mToolBlock.Inputs["LineA"].Value as CogLine;
CogLine lineB = mToolBlock.Inputs["LineB"].Value as CogLine;
///把lineA和lineB的坐标空间映射到输入图像的坐标空间中,创建lineAMapped和lineBMapped两条新的直线
CogLine lineAMapped = lineA.Map(image.GetTransform(image.SelectedSpaceName, lineA.SelectedSpaceName), CogCopyShapeConstants.All) as CogLine;
CogLine lineBMapped = lineB.Map(image.GetTransform(image.SelectedSpaceName, lineB.SelectedSpaceName), CogCopyShapeConstants.All) as CogLine;
///获取两条线的参考点 Line Reference Point(XY和角度R,该角度为相对于X轴的角度,以弧度表示)
double xA, yA, rA, xB, yB, rB;
lineAMapped.GetXYRotation(out xA, out yA, out rA); //获得lineAMapped参考点
lineBMapped.GetXYRotation(out xB, out yB, out rB); //获得lineBMapped参考点
/// 计算lineAMapped和lineBMapped 之间的角度
double dxA = Math.Cos(rA);
double dyA = Math.Sin(rA);
double dxB = Math.Cos(rB);
double dyB = Math.Sin(rB);
double dot= dxA * dxB + dyA * dyB; // dot为向量A和向量B的点积
dot = Math.Min(1.0, Math.Max(-1.0, dot)); //设定dot为单位向量-1.0 - 1.0之间的值
double angSpan = Math.Acos(dot); //获得两条直线之间的夹角
///通过判定找到角平分线的夹角MidAngle
double midAngle0 = rA + angSpan / 2.0; //LineA上方角度
double midAngle1 = rA - angSpan / 2.0; //LineA下方角度
double x0, y0, x1, y1;
x0 = Math.Cos(midAngle0); //LineA上方的参考点XY
y0 = Math.Sin(midAngle0);
x1 = Math.Cos(midAngle1); //LineA下方的参考点XY
y1 = Math.Sin(midAngle1);
double dot0 = x0 * dxB + y0 * dyB; //dot0 为上方参考点向量与LineB向量的点积
double dot1 = x1 * dxB + y1 * dyB; //dot1 为下方参考点向量与LineB向量的点积
double midAngle = midAngle0;
if (dot0 < dot1) //dotx 值越说明与LineB的夹角(Acos(dotx))越小,最终输出LineA和LineB两线之间的夹角
midAngle = midAngle1;
/// 计算角平分线的交点
CogLine cutLine = new CogLine();
cutLine.SelectedSpaceName = image.SelectedSpaceName;
cutLine.SetXYRotation((xA + xB) / 2.0, (yA + yB) / 2.0, midAngle+Math.PI/2.0); //创建一条角平分线的垂线
CogIntersectLineLineTool lineLineIntersectA = new CogIntersectLineLineTool(); //计算LineA和垂线CutLine的交点
lineLineIntersectA.InputImage = image;
lineLineIntersectA.LineA = cutLine;
lineLineIntersectA.LineB = lineAMapped;
lineLineIntersectA.Run();
CogIntersectLineLineTool lineLineIntersectB = new CogIntersectLineLineTool(); //计算LineB和垂线CutLine的交点
lineLineIntersectB.InputImage = image;
lineLineIntersectB.LineA = cutLine;
lineLineIntersectB.LineB = lineBMapped;
lineLineIntersectB.Run();
if (lineLineIntersectA.Intersects && lineLineIntersectB.Intersects) //如果LineA和LineB不平行,说明两线相交,则输出交点
{
double centerX= (lineLineIntersectB.X + lineLineIntersectA.X) / 2.0;
double centerY= (lineLineIntersectB.Y + lineLineIntersectA.Y) / 2.0;
CogLine midLine = new CogLine();
midLine.SelectedSpaceName = image.SelectedSpaceName;
midLine.SetXYRotation(centerX, centerY, midAngle);
mToolBlock.Outputs["MidLine"].Value = midLine; //输出角平分线(锐角)
mToolBlock.Outputs["MidLineAngle"].Value = CogMisc.RadToDeg( midAngle); //输出角平分线的角度(相对X轴的弧度)
}
return false;
}
5. 更多内容
V+视觉编程软件下载以及更多视觉资源内容请搜索”德创视觉之家“微信小程序或者关注”德创测控“公众号