Line perpendicular to 4 other lines

Hi all,

I am struggling and need some help.
I have been trying to get a line perpendicular to 4 lines where the end point is the same.

Hereby an image:


For this example I have 4 lines. The length of the lines are not the same and the center point is not planar with the start points of the 4 lines.

What I want to do is create the white line…

Hereby an example of the grid:

What I have been trying to do is add all Directions of the lines and divide it by the number of lines.
Then I get a vector3D that should be my direction, but this seems to fail sometimes…

Dim lineList As New List(Of Line)
Dim v1 As Vector3d = Nothing
For Each g As Guid In li
     Dim crv As Curve = New DocObjects.ObjRef(g).Curve
     Dim nwLine As New Line(crv.PointAtStart, crv.PointAtEnd)
     v1 += nwLine.Direction
     lineList.Add(nwLine)
Next
v1 /= li.Count

Dim myperpendicularlines New Line(lineList(0).To, v1 + lineList(0).To)

Most of them look correct, but some got their own mind and go wander somehow:

Anyone has any suggestion?

The direction of the curves are always towards the center.

P.S. I have tried to make all lines the same length, but does not fix the wild directions:

 nwLine.Extend(10 - nwLine.Length, 0)

If this is the case, then I don’t see how you are going to create a single line that is perpendicular.

To create a line that is perpendicular to two lines that share a start point, I’d create a two vectors from the the two lines and then calculate their cross product, which will give you the perpendicular direction.

Perhaps you need to do this for each set of lines and then calculate the average?

1 Like

I am now doing this for each 4 lines that have the same end point.

So it should work IF, I adjust the lines to the same length and then, add the directions and divide it by the number of lines.
(Dir1 + Dir2 + Dir3 + Dir4) / 4 = My Direction for the white line?

Or do I have the weird directions because of the 4 lines are not planar?

@jordy1989,

you might also fit a plane to the 4 line endpoints (and probably include the centerpoint as well), then get the normal of that plane and move it to the center point. Note that this does not guarantee that the normal is pointing “outward” as in your picture.

c.

1 Like

@clement you have given me a new idea…
4 points can’t create a planar srf. So I will create 2 triangles. Get the average normal of this one. Move it to the center point… Check the direction of the normal… Should work I guess…

The planes one worked like a charm:

solution (did not optimize it yet just tested it):

Dim c1 As Curve = New DocObjects.ObjRef(li(0)).Curve
Dim c2 As Curve = New DocObjects.ObjRef(li(1)).Curve
Dim c3 As Curve = New DocObjects.ObjRef(li(2)).Curve
Dim c4 As Curve = New DocObjects.ObjRef(li(3)).Curve

Dim sl1 As New Line(c1.PointAtStart, c1.PointAtEnd)
Dim sl2 As New Line(c2.PointAtStart, c2.PointAtEnd)
Dim sl3 As New Line(c3.PointAtStart, c3.PointAtEnd)
Dim sl4 As New Line(c4.PointAtStart, c4.PointAtEnd)

Dim pl1 As New Plane(c1.PointAtEnd, sl1.Direction, sl2.Direction)
Dim pl2 As New Plane(c1.PointAtEnd, sl2.Direction, sl3.Direction)
Dim pl3 As New Plane(c1.PointAtEnd, sl3.Direction, sl4.Direction)
Dim pl4 As New Plane(c1.PointAtEnd, sl4.Direction, sl1.Direction)

Dim d1 As Vector3d = pl1.Normal
Dim d2 As Vector3d = pl2.Normal
Dim d3 As Vector3d = pl3.Normal
Dim d4 As Vector3d = pl4.Normal

Dim dt As Vector3d = (d1 + d2 + d3 + d4) / 4

Dim lX As New Line(c1.PointAtEnd, dt + c1.PointAtEnd)
If c1.PointAtEnd.Z < dt.Z + c1.PointAtEnd.Z Then
     lX = New Line(c1.PointAtEnd, (New Point3d(0, 0, 0) - dt) + ((c1.PointAtEnd)))
End If
lX.Extend(0, height - dt.Length)
doc.Objects.AddLine(lX)

@jordy1989, i was thinking about using Plane.FitPlaneToPoints method and then changing the origin of the plane to the center point, then checking the normal orientation. But your solution using 4 triangles seems to work the same :wink:

c.

1 Like

@clement Didnt knew something like that existed. I will check it. Maybe faster than the way I am doing it since I need to declare a lot of stuff :stuck_out_tongue:

EDIT: Oke the result is the same:

Dim gPl As Plane = Nothing
Plane.FitPlaneToPoints({c1.PointAtStart, c2.PointAtStart, c3.PointAtStart, c4.PointAtStart}, gPl)
Dim dg As Vector3d = gPl.Normal
Dim lz As New Line(c1.PointAtEnd, dg + c1.PointAtEnd)
If c1.PointAtEnd.Z < dg.Z + c1.PointAtEnd.Z Then
     lz = New Line(c1.PointAtEnd, (New Point3d(0, 0, 0) - dg) + ((c1.PointAtEnd)))
End If
lz.Extend(0, height - dt.Length)
doc.Objects.AddLine(lz)
1 Like