一种求角平分线方法—VisionPro脚本实现

1. 角平分线定义:

  1. 从一个角的顶点引出一条射线(线在角内),把这个角分成两个完全相同的角,这条射线叫做这个角的角平分线(bisectorof angle)。

  2. 角平分线是在角的型内及形上,到角两边距离相等的点的轨迹。(具体如附图)

2. 在VisionPro中创建角平分线

  1. VisionPro中软件中没有提供封装好的角平分线工具,下面我 们介绍一种方法通过Vpro脚本实现角平分线的创建。

2. 求角平分线的脚本Angular bisector

3. 角平分线计算的理和过程

  1. 输入图像和直线A,B

  2. 把直线A,B的坐标空间映射到输入图像Image中,创建两条新 lineAMapped和lineBMapped

  3. 获取直线lineAMapped和直线lineAMapped上的参考点A(xA,yA,rA)和B(xB,yB,rB),这里的角度为指向相对于坐标系X轴的角度。

  4. 求取两条直线之间的角度β

  5. 计算两条直线平分线的角度MidAngle,这里需要判断是否为锐角

  6. 过两条直线上参考点的中心点建立一条垂直与角平分线的直线Cutline

  7. 分别求Cutline与lineAMapped的交点,以及Cutline与lineBMapped的交点,两个交点的中点设置为角平分线的参考点。

  8. 输出角平分线和对应角度(将弧度转换为角度)

  1. 运行效果如图

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+视觉编程软件下载以及更多视觉资源内容请搜索”德创视觉之家“微信小程序或者关注”德创测控“公众号

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值