Introduction

In many situations it is interesting to find the point closest to a line, and add a point in the line (like the dotted line in the picture above).
There exists a formula for finding the distance from a point to a line like the one
from MathWorld, but the problem with this is that it just finds the distance between an infinite extended line, based on two points on it, and a point.
This means it would not be constrained by the limits of the line created by the surrounding lines.

The standard way of finding out
which line
to add the point to is the Voronoi diagram of line segment. The solution is very accurate, but it is not trivial to implement from scratch, even if you
have a code for a normal Voronoi diagram of points. There are of course ready to use libraries,
which you would have to pay to use, and not viable for use,
and is in most cases (that I intend to use it for) a huge overkill. An example of such a Voronoi diagram could be seen below, were all the blue lines
shows (for the most part) the boundary that is equally far form two lines:

The algorithm that I will demonstrate would add the point if it is within the boundary of the blue line, meaning it would add the point to the closest line.

Background

There are several potential ways to solve this problem, one candidate would be to construct a Voroni diagram with lines, as described
here,
and this diagram would automatically set the boundaries for where the point should be added to the line. But unless
you have a pre programmed code that is ready to use, this is quite a task. So I would like a simple solution to the problem.

One solution is to design an algorithm that takes the bend of the curve into consideration, and won't add the point to the line section
if it is not within the boundaries. Boundaries are shown as red vectors in the picture below:

The Voroni diagram for a line would do this automatically.

Functions that are used

I must first describe some simple functions that is needed for the code to work. These are basic geometric functions that are used in several problems,
and would be useful to have regardless of the problem at hand.

First we need to find the angel between two connected lines, and this could be
done the "Law of cosine". The code below returns the angle in degrees.

The next issue is to find out which point the point is relative to the line, and this can be done by cross multiplication to find
the normal vector to the line, and is explained here. The code looks like this:

'''<summary>''' Finds which side of a line the point is
'''</summary>'''<paramname="PointToBeEvaluated">Evaluation point</param>'''<paramname="StartPointOnLine">Startpoint of line</param>'''<paramname="EndPointOnLine">Endpoint on line</param>'''<returns>-1 for a point to the right, 0 for a point on the line, +1 for a point to the left</returns>'''<remarks></remarks>PrivateFunction WhichSide(ByVal PointToBeEvaluated As Point, ByVal StartPointOnLine _
As Point, ByVal EndPointOnLine As Point) AsIntegerDim ReturnvalueEquation AsDouble
ReturnvalueEquation = ((PointToBeEvaluated.Y - StartPointOnLine.Y) _
* (EndPointOnLine.X - StartPointOnLine.X)) - ((EndPointOnLine.Y - StartPointOnLine.Y) _
* (PointToBeEvaluated.X - StartPointOnLine.X))
If ReturnvalueEquation > 0ThenReturn -1
ElseIf ReturnvalueEquation = 0ThenReturn0ElseReturn1EndIfEndFunction

One last function is needed for calculating the normal vector of a single line. This is nessesary for all the points.

The code can now be constructed from these simple functions. We will start off by calculating all the boundary lines (shown in red in the first picture),
and adding a vector that we could draw it in each point. The code is given below, an utilizes the functions above:

The first and the last point is calculated using, respectfully, the first and the last lines tilted at 90 and 270 degrees.

The angles of the other points are found by using the Law of cosine. The vector is calculated using the shortest angle, and if the calculated vector point
is on the same side as the first calculated vector point it is stored. If its on the opposite side, the vector is recalculated by withdrawing the angle from the full circle.

I simply calculate the distance from each line to the new point you are trying to intersect. However if the point is not within the boundaries the distance Double.MaxValue
is returned. This would guarantee that the point with the shortest distance is natural closest to the line in question.

The way I find out if the points are outside the boundary is to check whether the two boundary vectors are not equal to each other,
since we are evaluating the calculations on the distance this would work fine.

History

The code has massively been upgraded due to a bug. In addition the UI has also been upgraded, mostly in order to bug check the code, but it should also help you
understand the algorithm in more detail. Code is given in C# and VB and the main function is also encapsulated in a own class/module so it could easily be
implemented for others.

I see that inside InsertPoint You are initializing your min_distance with a starting value of 5000I would suggest you to avoid this approach, that is leading you to pick an arbitrary value that might be not large enough for all scenarios.

A better solution would be to initialize it to the value of the first iteration, then starting the For from 1 instead of 0.

Im sorry, but you cant do that, if the closest point is on line 2, but the distance from line 1 is closer, you would get the wrong answer. You would have to inizialize it some other way if this is going to work.

I would also like to mention that you can have a problem if you hit the exact boundery line, as it wouldnt see any of the two intersectiong lines as a valid point. The solution is to check witch side < 0 insted of < 1.