This Client Server article is republished in its entirety from 2004 for reference purposes.
By Yuedong Bi, Developer Support Analyst, Bentley Corporate Office 28 June 2004
In the Microstation 2004 Edition VBA Help (which can be found from Start > Programs > MicroStation > Documentation > Microstation VBA), you will find a brief introduction to the product's new features (Figure 1).
There are 14 new Segment3d members. This article will introduce most of them.
Figure 1: MVBA Help The Segment3d type definition can be found in MVBA help. It represents a line segment in a three-dimensional space. It has these members:
A Point3d value that represents the start of the segment.
A Point3d value that represents the end of the segment.
The StartPoint/EndPoint values are measured in the model's coordinate system. When you have placed a Segment3d in 3D space, you may have some questions, such as:
There are five Segment3d methods that can be used to create Segment3d objects:
Example: Suppose there is a cube in 3D space (Figure 2). pointA to pointN are defined as the Point3d type. segmentAB, segmentBC etc., are defined as the Segment3d type.
Dim pointA as Point3d
Dim segmentAB as Segment3d
Figure 2: 3D cube segmentAB can be created by:
segmentAB = Segment3dFromXYZXYZStartEnd(0, 0, 0, 0, 10, 0)
segmentAB = Segment3dFromPoint3dStartEnd(pointA, pointB)
segmentAB = Segment3dFromPoint3dStartTangent(pointA, tangentAB)
Where tangentAB is a Point3d type, it is the extent from start point A.
The value is (0, 10, 0).
Q: To create segmentME with start point M(20,10,10), what is the tangent?
A: It should be (-10, -10, -10). This is the vector from the start point to the end point. Segment3dFromRay3d () is demonstrated in the attached example code.
Q: Are segmentAB and segmentBA same?
A: No. According to definition, they are different. Their start and end points are stored in reverse order, and fractional coordinates (from 0 to 1) advance in opposing directions on segments with exchanged start and end points.
A Segment3d is a type in MVBA, not a MicroStation Element. You can map it to a line element, and you can translate them back and forth through vertices.
To create a line element from segmentAB in Microstation VBA:
Dim LineElement as LineElement
Set LineElement = CreateLineElement2 _
(Nothing, segmentAB .StartPoint, segmentAB.EndPoint)
To create a mySegment from a line element:
Dim mySegment as Segment3d
mySegment = Segment3dFromPoint3dStartEnd(myLine.startPoint, _
The reason we create a Segment3d type is to allow the user to find the relationships between points, line segments, and planes.
The Segment3dSegment3dIntersectXY method computes a point closest to a space point, and on an unbounded line, using only xy coordinates in projection calculation. This is the point at which the two segments appear to cross each other when viewed while looking directly at the xy plane. Because the two segments may be at different depths when they appear to cross, the method returns two intersection points: one is the point on the first segment, and the other is the point on the second segment. The xy parts of the two points will be identical, but the z parts may be different.
The Segment3dPlane3dIntersect method computes the intersection of an unbounded segment and a plane. It returns "true" if there is an intersection point, or else "false" if a segment is parallel, or coincident to the plane.
There is an output parameter fraction; this is the fractional position of the intersection point along a Segment. Fractional positions 0, ½ and 1 are (respectively) the start, midpoint, and endpoint. Fractional positions less than 0 are "before" the start, and fractional positions larger than 1 are "beyond" the endpoint.
For example: In Figure 3, suppose segment AB and CD intersect at point E. The fraction for segment AB will be length(AE)/length(AB). The fraction for segment CD will be length(CE)/length(CD).
Figure 3: Fraction Demo In Figure 2, we know the intersection of segmentAD and segmentDG is point D,
So, the fraction for AD will be 1. For DG, it will be 0.
To verify this, run:
status = Segment3dSegment3dIntersectXY(segmentAD, segmentDG, point0, _
fraction0, point1, fraction1)
You will get point0 = point1 = (10, 0, 10), fraction0=1, fraction1=0.
The detail is documented in the MVBA Help.
The Segment3dSegment3dClosestApproach method will compute the closest approach of two lines in 3D, considering both lines unbounded. It returns false if parallel or coincident, otherwise it returns true.
If you are looking for the true 3D intersection between segments, call the "closest approach" method and check if the two points it returns are identical. If so, this is the intersection. If not, your lines are "passing in space" and never intersect!!
For example, in Figure 2 we know the closest approach between segmentAB and segmentDG is segmentAD. The following code will verify this:
' Closest approach of AB and DG
status = Segment3dSegment3dClosestApproach(segmentAB, segmentDG, _
point0, fraction0, point1, fraction1)
'Result should be: point0 (0, 0, 0), point1 (0, 0, 10), fraction0=0, fraction1=0
You should check the return status before reading closest approach points and fractions. If two segments are parallel or coincident, point0/point1, fraction0/fraction1 will be meaningless.
To get the offset distance between two parallel segments, call method Segment3dClosestPoint to project a point from one segment onto the other segment.
Segment3dClosestPointBounded(), Segment3dClosestPoint(), Segment3dClosestPointBoundedXY(), Segment3dClosestPointXY() Compute a point (returned) closest to a space point (known) on a line (known).
The differences are as follows:
Function (Method)Consider the line as bounded?Project to XY plan?
(Ignore Z Value)Segment3dClosestPointBoundedYesNoSegment3dClosestPointNoNoSegment3dClosestPointBoundedXYYesYesSegment3dClosestPointXYNoYes
If the returned closest point (Figure 4), Point E is within a segment (segmentAB), Segment3dClosestPointBounded () and Segment3dClosestPoint (), it will return same result (Figure4), Point E.
Figure 4: Closest point If the closest point (Figure 4), pointF is outside a segment (segmentAB), Segment3dClosestPointBounded () will return an end point (Figure 4), pointB,
Segment3dClosestPoint () will return a point outside the segment (Figure 4), pointF.
After an unbounded calculation, you can decide if the projected point is inside or outside the bounded segment by testing if the fractional position is between zero and one.
For example (refer to Figure 2):
Dim closestPoint As Point3d
Dim closestFraction As Double
Segment3dClosestPoint segmentAG, pointD, closestPoint, closestFraction
Segment3dClosestPointBounded segmentAG, pointD, closestPoint, _
‘Result: closestPoint (3.3, 3.3, 3.3), closestFraction=0.333
Segment3dClosestPointXY segmentAG, pointD, closestPoint, closestFraction
Segment3dClosestPointBoundedXY segmentAG, pointD, closestPoint, _
‘ Result: closestPoint (0, 0, 0), closestFraction=0,
‘ Because we project pointD and segmentAG to XY plan.
To demonstrate the difference between the bounded and unbounded method, let's compute a point on segmentME closest to pointA (Figure 2).
Segment3dClosestPoint segmentME, pointA, closestPoint, closestFraction
' Result: closestPoint (6.667, -3.333, -3.333) closestFraction = 1.3333
‘ If fraction great then 1, which means it is out of the segment.
Segment3dClosestPointBounded segmentME, pointA, closestPoint, _
‘Result: closestPoint (10, 0, 0), closestFraction = 1
As you can see, the bounded method returns a fraction between 0 and 1; if the computed point is outside of the segment, it returns the start or end point.
Client Server Archive
MicroStation Desktop TechNotes and FAQs
Bentley's Technical Support Group requests that you please confine any comments you have on this Wiki entry to this "Comments or Corrections?" section. THANK YOU!