Bisector between two 3D lines

I need to locate a CS point at the intersection of two 3D lines that are not in the same plane. The CS point needs to be rotated (around Z) half of the angle of the two 3D lines. in other words it needs to be half the angle of the bearing difference of the two .3D lines. please also refer to bisector.dgn link below, this is a bisector script but it calculates the half angle of 3d lines in any direction

/cfs-file/__key/communityserver-discussions-components-files/360/bisector.dgn

this image shows the CS rotated half the bearing angle between the two lines. looking in plan regardless of lines being 2D or 3D 

( bearing is the horizontal angle between the direction of an object and another object, or between it and that of true north.)

Parents
  • Here a Version using a sheared CS. 

    function (PolyLine P_track)
    {
        for (int i = 1; i < P_track.Vertices.Count-1 ; ++i)
        {
            Point dir_point = new Point(this);
            CoordinateSystem shear_cs = new CoordinateSystem(this);
            shear_cs.ByOriginPrimarySecondaryDirections(P_track.Vertices[i],P_track.Vertices[i-1],AxisOption.X,P_track.Vertices[i+1],AxisOption.Y,TransformOption.Sheared);
            double x1 = shear_cs.ShearAngle/2;
            dir_point.ByCartesianCoordinates(shear_cs,1,1,0);
            Line angle_line = new Line(this);
            angle_line.ByStartPointDirectionLength(P_track.Vertices[i],dir_point, 10);
        }
    }



  • Hi Richard,

    I recall Volker doing something like that in one of the sigs and it worked for angles over 180, but I can't recall it off hand.

    Without going into a scripting side you could just use a circle divide it up using the arc segment and then measure the sweep angle.

    Not sure how that would work if you had hundreds of points to measure but it is a good approach to measure angles.

    here is an updated script file

    Divide-update.txt
    transaction 1 stateChange 'Add baseCS'
    {
        gcModel
        {
            node User.Objects.baseCS Bentley.GC.NodeTypes.CoordinateSystem
            {
                Technique                 = 'AtDGNModelOrigin';
                DGNModelName              = 'Design Model';
                SymbolSize                = 1;
                GraphLocation             = <auto> {40.0, 40.0, 0.0, 116.37};
            }
        }
    }
    
    transaction 2 stateChange 'Add line1_EndPoint, line1_StartPoint'
    {
        gcModel
        {
            node User.Objects.line1_StartPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'OnPlane';
                Plane                     = User.Objects.baseCS.XYPlane;
                XTranslation              = <free> 4803.84954526119;
                YTranslation              = <free> 3043.39161735525;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = <auto> {314.0, 40.0, 0.0, 142.41};
            }
            node User.Objects.line1_EndPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'OnPlane';
                Plane                     = User.Objects.baseCS.XYPlane;
                XTranslation              = <free> 9803.84954526118;
                YTranslation              = <free> 3043.39161735525;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = <auto> {314.0, 222.41, 0.0, 142.41};
            }
        }
    }
    
    transaction 3 stateChange 'Add line1'
    {
        gcModel
        {
            node User.Objects.line1 Bentley.GC.NodeTypes.Line
            {
                Technique                 = 'ByPoints';
                StartPoint                = User.Objects.line1_StartPoint;
                EndPoint                  = User.Objects.line1_EndPoint;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = <auto> {588.0, 40.0, 0.0, 129.39};
            }
        }
    }
    
    transaction 4 stateChange 'Add line2_EndPoint'
    {
        gcModel
        {
            node User.Objects.line2_EndPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ByCartesianCoordinates';
                CoordinateSystem          = User.Objects.baseCS;
                XTranslation              = <free> 6763.62237296726;
                YTranslation              = <free> 7244.88788706733;
                ZTranslation              = <free> 3535.53390593274;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = {318.667, 379.333, 0.0, 155.43};
            }
        }
    }
    
    transaction 5 stateChange 'Add line2'
    {
        gcModel
        {
            node User.Objects.line2 Bentley.GC.NodeTypes.Line
            {
                Technique                 = 'ByPoints';
                StartPoint                = User.Objects.line1_StartPoint;
                EndPoint                  = User.Objects.line2_EndPoint;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = {600.0, 276.0, 0.0, 129.39};
            }
        }
    }
    
    transaction 6 stateChange 'Add point1, point2, point3'
    {
        gcModel
        {
            node User.Objects.point1 Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ProjectOntoPlane';
                Plane                     = baseCS.XYPlane;
                PointToProjectOntoPlane   = line1.EndPoint;
                GraphLocation             = {1014.013, -34.627, 0.0, 129.39};
            }
            node User.Objects.point2 Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ProjectOntoPlane';
                Plane                     = baseCS.XYPlane;
                PointToProjectOntoPlane   = line2.EndPoint;
                GraphLocation             = {1006.933, 261.693, 0.0, 129.39};
            }
            node User.Objects.point3 Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ProjectOntoPlane';
                Plane                     = baseCS.XYPlane;
                PointToProjectOntoPlane   = line1.StartPoint;
                GraphLocation             = {1010.773, 105.213, 0.0, 129.39};
            }
        }
    }
    
    transaction 7 stateChange 'Add MeasureAngle'
    {
        gcModel
        {
            node User.Objects.MeasureAngle Bentley.GC.NodeTypes.FunctionCall
            {
                Technique                 = 'Default';
                Function                  = Angle;
                origin                    = point3;
                point1                    = point1;
                point2                    = point2;
                GraphLocation             = {1358.653, 26.813};
            }
        }
    }
    
    transaction 8 stateChange 'Add RoataeCS'
    {
        gcModel
        {
            node User.Objects.RoataeCS Bentley.GC.NodeTypes.CoordinateSystem
            {
                Technique                 = 'ByOriginRotationAboutCoordinateSystem';
                Origin                    = point3;
                CoordinateSystem          = baseCS;
                RotationAngle             = MeasureAngle/2;
                Axis                      = AxisOption.Z;
                GuideRadius               = 1.0;
                GraphLocation             = {1629.373, 59.453, 0.0, 155.43};
            }
        }
    }
    
    transaction 9 stateChange 'Add DividePoint'
    {
        gcModel
        {
            node User.Objects.DividePoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ByDirectionAndDistanceFromOrigin';
                Origin                    = point3;
                Direction                 = RoataeCS.XDirection;
                DistanceFromOrigin        = 3000;
                GraphLocation             = {1931.773, 57.533};
            }
        }
    }
    
    transaction 10 stateChange 'Change line2_EndPoint'
    {
        gcModel
        {
            node User.Objects.line2_EndPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ByCartesianCoordinates';
                XTranslation              = <free> 6147.21945082577;
                YTranslation              = <free> 7711.62994488677;
            }
        }
    }
    
    transaction 11 stateChange 'Add arc1, circle1, curve1, NewAngle, point4; change DividePoint, line2_EndPoint, MeasureAngle, RoataeCS'
    {
        gcModel
        {
            node User.Objects.line2_EndPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ByCartesianCoordinates';
                XTranslation              = <free> 3746.30440871748;
                YTranslation              = <free> -1331.71239731185;
            }
            node User.Objects.MeasureAngle Bentley.GC.NodeTypes.FunctionCall
            {
                GraphLocation             = {1587.619, -141.427, 0.0, 153.37};
            }
            node User.Objects.circle1 Bentley.GC.NodeTypes.Circle
            {
                Technique                 = 'ByCenterRadius';
                CenterPoint               = point3;
                Radius                    = 1000;
                Support                   = baseCS.XYPlane;
                GraphLocation             = {1417.907, 256.621};
            }
            node User.Objects.curve1 Bentley.GC.NodeTypes.Curve
            {
                Technique                 = 'FromPointSet';
                PointSet                  = {point1,point3,point2};
                CurveFromPointSetOption   = CurveFromPointSetOption.PolyLine;
                GraphLocation             = {1557.222, 442.362};
            }
            node User.Objects.point4 Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'AtCurveCurveIntersection';
                Curve0                    = circle1;
                Curve1                    = curve1;
                TreatLinesAsInfinite      = false;
                GraphLocation             = {1778.445, 275.629, 0.0, 156.43};
            }
            node User.Objects.arc1 Bentley.GC.NodeTypes.Arc
            {
                Technique                 = 'SplitAtPoint';
                ArcToSplit                = circle1;
                SplitPoint                = point4[0];
                GraphLocation             = {2048.627, 285.421};
            }
            node User.Objects.NewAngle Bentley.GC.NodeTypes.Value
            {
                Technique                 = 'Default';
                Value                     = arc1[0].SweepAngle;
                GraphLocation             = {2483.507, 310.381};
            }
            node User.Objects.RoataeCS Bentley.GC.NodeTypes.CoordinateSystem
            {
                Technique                 = 'ByOriginRotationAboutCoordinateSystem';
                RotationAngle             = NewAngle/2;
                GraphLocation             = {2456.048, -19.344};
            }
            node User.Objects.DividePoint Bentley.GC.NodeTypes.Point
            {
                GraphLocation             = {2758.448, -21.264};
            }
        }
    }

    let me know how it goes.

    Maybe a custom small function will be what you need. I would have a look through the old SIGs as well.

    Hope that helps

    Wayne

Reply
  • Hi Richard,

    I recall Volker doing something like that in one of the sigs and it worked for angles over 180, but I can't recall it off hand.

    Without going into a scripting side you could just use a circle divide it up using the arc segment and then measure the sweep angle.

    Not sure how that would work if you had hundreds of points to measure but it is a good approach to measure angles.

    here is an updated script file

    Divide-update.txt
    transaction 1 stateChange 'Add baseCS'
    {
        gcModel
        {
            node User.Objects.baseCS Bentley.GC.NodeTypes.CoordinateSystem
            {
                Technique                 = 'AtDGNModelOrigin';
                DGNModelName              = 'Design Model';
                SymbolSize                = 1;
                GraphLocation             = <auto> {40.0, 40.0, 0.0, 116.37};
            }
        }
    }
    
    transaction 2 stateChange 'Add line1_EndPoint, line1_StartPoint'
    {
        gcModel
        {
            node User.Objects.line1_StartPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'OnPlane';
                Plane                     = User.Objects.baseCS.XYPlane;
                XTranslation              = <free> 4803.84954526119;
                YTranslation              = <free> 3043.39161735525;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = <auto> {314.0, 40.0, 0.0, 142.41};
            }
            node User.Objects.line1_EndPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'OnPlane';
                Plane                     = User.Objects.baseCS.XYPlane;
                XTranslation              = <free> 9803.84954526118;
                YTranslation              = <free> 3043.39161735525;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = <auto> {314.0, 222.41, 0.0, 142.41};
            }
        }
    }
    
    transaction 3 stateChange 'Add line1'
    {
        gcModel
        {
            node User.Objects.line1 Bentley.GC.NodeTypes.Line
            {
                Technique                 = 'ByPoints';
                StartPoint                = User.Objects.line1_StartPoint;
                EndPoint                  = User.Objects.line1_EndPoint;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = <auto> {588.0, 40.0, 0.0, 129.39};
            }
        }
    }
    
    transaction 4 stateChange 'Add line2_EndPoint'
    {
        gcModel
        {
            node User.Objects.line2_EndPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ByCartesianCoordinates';
                CoordinateSystem          = User.Objects.baseCS;
                XTranslation              = <free> 6763.62237296726;
                YTranslation              = <free> 7244.88788706733;
                ZTranslation              = <free> 3535.53390593274;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = {318.667, 379.333, 0.0, 155.43};
            }
        }
    }
    
    transaction 5 stateChange 'Add line2'
    {
        gcModel
        {
            node User.Objects.line2 Bentley.GC.NodeTypes.Line
            {
                Technique                 = 'ByPoints';
                StartPoint                = User.Objects.line1_StartPoint;
                EndPoint                  = User.Objects.line2_EndPoint;
                Color                     = Colors.White;
                FillColor                 = Colors.None;
                LevelName                 = 'Default';
                LineStyleName             = '0';
                LineWeight                = 0;
                Transparency              = 0.0;
                GraphLocation             = {600.0, 276.0, 0.0, 129.39};
            }
        }
    }
    
    transaction 6 stateChange 'Add point1, point2, point3'
    {
        gcModel
        {
            node User.Objects.point1 Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ProjectOntoPlane';
                Plane                     = baseCS.XYPlane;
                PointToProjectOntoPlane   = line1.EndPoint;
                GraphLocation             = {1014.013, -34.627, 0.0, 129.39};
            }
            node User.Objects.point2 Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ProjectOntoPlane';
                Plane                     = baseCS.XYPlane;
                PointToProjectOntoPlane   = line2.EndPoint;
                GraphLocation             = {1006.933, 261.693, 0.0, 129.39};
            }
            node User.Objects.point3 Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ProjectOntoPlane';
                Plane                     = baseCS.XYPlane;
                PointToProjectOntoPlane   = line1.StartPoint;
                GraphLocation             = {1010.773, 105.213, 0.0, 129.39};
            }
        }
    }
    
    transaction 7 stateChange 'Add MeasureAngle'
    {
        gcModel
        {
            node User.Objects.MeasureAngle Bentley.GC.NodeTypes.FunctionCall
            {
                Technique                 = 'Default';
                Function                  = Angle;
                origin                    = point3;
                point1                    = point1;
                point2                    = point2;
                GraphLocation             = {1358.653, 26.813};
            }
        }
    }
    
    transaction 8 stateChange 'Add RoataeCS'
    {
        gcModel
        {
            node User.Objects.RoataeCS Bentley.GC.NodeTypes.CoordinateSystem
            {
                Technique                 = 'ByOriginRotationAboutCoordinateSystem';
                Origin                    = point3;
                CoordinateSystem          = baseCS;
                RotationAngle             = MeasureAngle/2;
                Axis                      = AxisOption.Z;
                GuideRadius               = 1.0;
                GraphLocation             = {1629.373, 59.453, 0.0, 155.43};
            }
        }
    }
    
    transaction 9 stateChange 'Add DividePoint'
    {
        gcModel
        {
            node User.Objects.DividePoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ByDirectionAndDistanceFromOrigin';
                Origin                    = point3;
                Direction                 = RoataeCS.XDirection;
                DistanceFromOrigin        = 3000;
                GraphLocation             = {1931.773, 57.533};
            }
        }
    }
    
    transaction 10 stateChange 'Change line2_EndPoint'
    {
        gcModel
        {
            node User.Objects.line2_EndPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ByCartesianCoordinates';
                XTranslation              = <free> 6147.21945082577;
                YTranslation              = <free> 7711.62994488677;
            }
        }
    }
    
    transaction 11 stateChange 'Add arc1, circle1, curve1, NewAngle, point4; change DividePoint, line2_EndPoint, MeasureAngle, RoataeCS'
    {
        gcModel
        {
            node User.Objects.line2_EndPoint Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'ByCartesianCoordinates';
                XTranslation              = <free> 3746.30440871748;
                YTranslation              = <free> -1331.71239731185;
            }
            node User.Objects.MeasureAngle Bentley.GC.NodeTypes.FunctionCall
            {
                GraphLocation             = {1587.619, -141.427, 0.0, 153.37};
            }
            node User.Objects.circle1 Bentley.GC.NodeTypes.Circle
            {
                Technique                 = 'ByCenterRadius';
                CenterPoint               = point3;
                Radius                    = 1000;
                Support                   = baseCS.XYPlane;
                GraphLocation             = {1417.907, 256.621};
            }
            node User.Objects.curve1 Bentley.GC.NodeTypes.Curve
            {
                Technique                 = 'FromPointSet';
                PointSet                  = {point1,point3,point2};
                CurveFromPointSetOption   = CurveFromPointSetOption.PolyLine;
                GraphLocation             = {1557.222, 442.362};
            }
            node User.Objects.point4 Bentley.GC.NodeTypes.Point
            {
                Technique                 = 'AtCurveCurveIntersection';
                Curve0                    = circle1;
                Curve1                    = curve1;
                TreatLinesAsInfinite      = false;
                GraphLocation             = {1778.445, 275.629, 0.0, 156.43};
            }
            node User.Objects.arc1 Bentley.GC.NodeTypes.Arc
            {
                Technique                 = 'SplitAtPoint';
                ArcToSplit                = circle1;
                SplitPoint                = point4[0];
                GraphLocation             = {2048.627, 285.421};
            }
            node User.Objects.NewAngle Bentley.GC.NodeTypes.Value
            {
                Technique                 = 'Default';
                Value                     = arc1[0].SweepAngle;
                GraphLocation             = {2483.507, 310.381};
            }
            node User.Objects.RoataeCS Bentley.GC.NodeTypes.CoordinateSystem
            {
                Technique                 = 'ByOriginRotationAboutCoordinateSystem';
                RotationAngle             = NewAngle/2;
                GraphLocation             = {2456.048, -19.344};
            }
            node User.Objects.DividePoint Bentley.GC.NodeTypes.Point
            {
                GraphLocation             = {2758.448, -21.264};
            }
        }
    }

    let me know how it goes.

    Maybe a custom small function will be what you need. I would have a look through the old SIGs as well.

    Hope that helps

    Wayne

Children