Simple math algorithm: Center point of a line - algorithm

I have an algorithm as follows for finding the center of a line (midpoint).
public DoublePoint getMidPoint() {
return new DoublePoint((origin.x + endPoint.x) / 2, (origin.y + endPoint.y) / 2);
}
It seems to work for any values. But I seem to remember a much more complex algorithm, involving two circles whose radius equals the length of the line and whose center points are the ends of the line. A line drawn from the intersection of those circles would intersect the line segment you are testing, giving the line's midpoint. I know for sure that algorithm works 100% of the time. Not sure about my simpler algorithm which seems too simple.

What you are remembering is a geometric method of constructing the perpendicular bisector of a line segment using only a compass and straightedge. Consider, for instance:
This was fine for the ancient Greeks, but there are other methods (such as the one you have coded) which work better for computers.

Your simple algoritm is full correct. Method with circles is a finding the midpoint with pair of compasses.

The algorithm you vaguely remember is to use a straightedge and a compass to get the midpoint. Draw take two equal radius circles centered on the two ends of the line segment in such way that they intersect -- the length of the line segment will do. Use the straightedge to connect the points where the circles intersect. Where this line intersects the original line segment is the midpoint. Fancy animation at http://www.mathopenref.com/constbisectline.html

The algorithm and code you have is the simplest and best way to do this.

Your algorithm is a simplification of translating the line to the origin, finding the vector represented by that line, halving it, then translating it back to the original line. The simplification is valid, and the algorithm is correct.

Related

Algorithm to find the largest inscribed chord of a closed polyline

I'm looking for an algorithm to find the longest chord ("diameter") of a closed polyline. Unfortunately that polyline doesn't have to be convex, but the chord should lie entirely within the curve. Here's an example:
The solution I'm looking for is the dashed red segment.
Can you suggest an efficient algorithm for this? The best we've been able to achieve so far is the N² algorithm that tries all pairs of vertices, but even that seems incorrect since the chord doesn't necessarily pass through two vertices (or does it?).
I'm also interested in the related problem where we are looking for the biggest segment joining two vertices (or the longest part of that segment that lies within the curve if the segment in not fully inscribed). In that case, the N² algorithm works, but is slow for a large number of points.
I think the solution will always include at-least two vertex. So calculating a list all the lines segments between all the vertex, including the one extending to touch another of the polygon's line segment will do the trick.
To calculate if any of the line segment converted to ray will intersect with another line segment see the answer:
How do you check for intersection between a line segment and a line ray emanating from a point at an angle from horizontal?
After that check if our list of line segments are fully within the polygon. The following answer will allow you to check that, eliminating the ones going out of bounds.
determine if line segment is inside polygon
Now the longest of the remaining should be the answer.

finding boundaries of circle division by straight line

Given a circle, I add a straight line that goes through the circle and intersects it at two points as well as intersects every previous line at one point.
I want to repeat this procedure (adding one straight line at a time) and figure out the points that make up the boundaries of the sections the circle is divided into.
For example the first time I do this (first line) it divides the circle into 2 pieces:
When I add a second line it will divide each of these 2 pieces of the circle into 4 pieces:
When I add a third line it will divide the circle into 7 pieces:
What is an efficient algorithm to get these points?
Every time I add a line I can compute all the points that line intersects the circle and the other previous lines but I have to somehow figure out which regions these points are the boundary to
Not sure I completely understand the question but:
1) line/line intersection is achieved by Cramer. http://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
2) line/circle intersection is achieved by solving a quadratic equation http://mathworld.wolfram.com/Circle-LineIntersection.html
3) you can classify the points per region by considering all signs obtained when injecting the point coordinates in the parametric equation of the splitting lines (in other words, is the point on the left or on the right of the line); this gives you a binary labeling of all regions (some of the labels being impossible).
You can also consider a ternary notation if you need to handle points known to be exactly on a line.

Algorithm for finding empty areas

does anybody know of a good algorithm for this task:
a multi polygon contains the reserved areas
find an empty position for the given polygon which is closest to its original position but does not intersect the reserved areas
I have implemented some very basic algorithm which does the job but far from optimally.
Thank You!
Edit:
my solution basically does the following:
move given polygon in all possible directions dx and dy
check wether the new intersection is less than the previous intersection
if so, use new position and make sure that you don't move your polygon back and forth at the same position
repeat these steps a maximum of N times
Example: it is intended for placing text which should not overlap with each other.
One method that immediately pops into my mind is to shoot a ray (i.e. measure a line segment) from the original position to every vertex of the polygon. Do a comparison on those distances, and then based on those comparisons, narrow it down to the minimally far away line segment of the polygon. Compute the perpendicular intersection of that line with the origin, and you'll get the minimally far away point. If the vertex comparisons don't lead you down the right path, just shoot off lines in random directions, and just stop when you're happy with the result. It doesn't sound like you require optimality.
Let's look at the original problem: making sure that one piece of text doesn't overlap another. Presumably this is for labelling a map. The way I do it is this: draw the text invisibly, checking for overlap (by using a specialised graphics context that instead of drawing a pixel, checks whether a pixel is already there) then try another position along the line on which the text is to be placed - usually a street. I try the middle of the line first, then successive positions further and further left and right of the middle. If that fails I try again with a condensed (narrower) font.

Determining a mean camber line

Fellow programmers,
I know this is a little outside your juridistiction, but I was wondering perhaps if you have time, if you could help me with one "procedure". Not in view of math but what would be the best way to take.
This is an airfoil / profile. Usually, profiles are defined with two sets of data. One is the position of mean camber line, given in the form of x,y where x is usually given in percentages of chord length. Second set of data is thickness at percentages of chord length. Thickness is always drawn perpendicular to the camber line(!), and that gives the profile points.
Now, I have a reverse problem - I have points of a profile, and I need to determine the position of the camber line. Method of interpolation through points can vary, but it doesn't matter, since I can always interpolate as many points as I need, so it comes to linear in the end.
Remember, since the thinkness is drawn perpendicular to the camber line, the position of camber line is not mean between the points of upper and lower line of profile (called the back and face of profile).
Edit (how this is done on paper): Uhh, painfully and in large scale (I'm talking long A0 paper here, that is 1189x5945mm on a large drawing desk. You start by drawing a first camber line (CL) iteration through the midpoints (mean points) between the points of face and back at same x ordinates. After that you draw a lot of perpendicular lines, perpendicular to that CL, and find their midpoints between face and back (those points on face and back will no longer have same x values). Connect those, and that is your second iteration CL. After that you just repeat the second step of the procedure by drawing perpendicular lines onto that 2nd CL ... (it usually converges after 3 or 4 iterations).
2nd Edit: Replaced the picture with one which better shows how the thinkness is "drawn" onto the camber line (CL). Another way of presenting it, would be like picture no.2. If you drew a lot of circles, whoce center points are at the camber line, and whose radiuses were the amounts of thickness, then tangents to those circles would be the lines (would make up the curve) of the profile.
The camber line is not the mean line (mean between the points of face and back); it can coincide with it (therefore usually the confusion). That difference is easily seen in more cambered profiles (more bent ones).
3rd edit - to illustrate the difference dramatically (sorry it took me this long to draw it) between the mean line and camber line, here is the process of how it is usually done "on paper". This is a rather deformed profile, for the reason, that the difference between the two can be more easily shown (although profiles like this exist also).
In this picture the mean line is shown - it is a line formed by the mean values of face and back on the same x coordinates.
In this picture onto the mean line, perpendicular lines were drawn (green ones). Midpoints of those perpendicular lines make up for the 1st iteration of the camber line (red intermittent line). See how those circles fit better inside the airfoil compared to the first picture.
In the picture below the 2nd iteration of the camber line is shown, along with the mean line from the first picture as to illustrate the difference between the two. Those circles are fitting even better now inside (except that first one which flew out, but don't mind him).
From what I can gather from your diagram, the camber line is defined by it being the line whose tangent bisects the angle between the two tangents of the upper and lower edges.
In other words, your camber line is always the mean point between the two edges, but along a line of shortest distance between the top and bottom edges.
So, given the y-coordinates y=top(x) and y=bot(x), why don't you:
<pseudocode>
for each x:
find x2 where top(x)-bot(x2) is minimized
camber( mean(x,x2) ) = mean( top(x),bot(x2) )
</pseudocode>
and then interpolate etc.?
edit
Sorry! On second thought I think that should be
find x2 where ( (top(x)-bot(x2))^2 + (x-x2)^2 ) is minimised
obviously you should be minimising the length of that perpendicular line.
Is that right?
I'm new to stack overflow but this is a problem I have worked on quite a bit and thought I would post an alternate approach to the problem.
This approach uses the concept of a Voronoi diagram:
http://en.wikipedia.org/wiki/Voronoi_diagram
Essentially, a map is created which divides the space into regions containing one of the input points (x,y of your airfoil). The important part here is that any point within the region is closest to the input point in that region. The nodes created by this space division are equidistant to at least three of the input points.
Here is the interesting part: three equidistant points from a center point can be used to create a circle. As you mentioned, inscribed circle center points are used to draw the mean camber line because the inscribed circle measures the thickness.
We are close now. The nature of the voronoi diagram in this application means that any voronoi node inside of our airfoil region is the center point of one of these "thickness circles." (This runs into some issue very close to the LE and TE depending on your data. I usually apply some filtering here).
Basic Structure:
Create Voronoi Diagram
Extract Voronoi Nodes
Determine Nodes Which Lie Within Airfoil
Construct Mean Camber Line From Interior Nodes
Most of my work is in Matlab which has built in voronoi and inpolygon functions. As such, I'm not a huge help in developing those functions but they should be well documented elsewhere.
Trailing Edge/Leading Edge Issues
As I am sure you have experienced or know, it is difficult to measure thickness well when close to the LE/TE. This approach will contruct a fork in the nodes when the thickness circle is less than the edge radius. A check of the data for this fork will find the points which are false for the camber line. To construct the camber line all the way to the edge of the foil you could extrapolate your camber line (2nd or 3rd order should be fine) and find the intersection.
I think the best way for drawing the camber line of an airofoil is to load the profile in CATIA. After that in CATIA we can draw circles that are tangent to the both side of profile (suction side and pressure side. Then we can connect center of these circles and consequently we find the camber line accurately.
Is the mean camber line the set of points equidistant from the upper line and the lower line? If that's the definition, it's different from Sanjay's, or at least not obviously-to-me the same.
The most direct way to compute that: cast many rays perpendicular to the upper line, and many rays perpendicular to the lower line, and see where the rays from above intersect the rays from below. The intersections with the nearest-to-equal distances approximate the mean camber line (as defined here); interpolate them, with the differences in distance affecting the weights.
But I'll bet the iterative method you pasted from comments is easier to code, and I guess would converge to the same curve.

Minimum perpendicular Distance of a point to a line in 3D plane algorithm

How to find the minimum perpendicular distance of point from a line in 3D plane?
Please give me the logic and I will try to code on myself.
Please let me know how to do it in terms of x,y,z that is in terms of coordinate systems.
I am finding it a bit difficult to find the right solution which will be easy from a coding point of view. Online solutions are little bit rusty to understand. So please help me.
Please note line is given in terms of 3D space equation.
Given point A and a line, pick two different points on the line (B and C). Calculate the area of the triangle ABC with use of Heron's formula. Multiply the area by 2 and divide it by length of [BC]. You have the result you needed.
For an infinite line, the minimum distance is the length of line segment at right-angles to the infinite line passing through the point starting at the line and ending at the point. The direction of the perpendicular is given by the cross product of the unit normal to the plane and the unit vector along the line, the foot of the perpendicular is given by simultaneous solution of the equation for the first line, and for the perpendicular through the point. The distance between the points is what you are after.
For a finite line, this is a solution only if the foot of the perpendicular is on the segment; otherwise it's the shorter of the distance between the point and either end of the segment.
You say the line is given as an equation in 3D, but really planes are given by equations. And since the line is said to be lying in a 3D plane, presumably given by another equation, the line is actually the intersection of two planes.
To get the direction vector of the line, take the cross product of the normals to the two planes. If you use Pavel's method, you don't need this.
To get a point on the line, pick some value for x, say x = 0. Then solve the two equations for y and z after plugging in that value. To find another point to use in Pavel's method, set x to some other value, say x = 1, and solve the system again.
If the line is oriented the wrong way (perpendicular to the x axis), x may be a fixed value. In that case, try setting y to two fixed values. If that still doesn't work, try z. Also, check that the original planes are not parallel, so that there actually is a line of intersection.
To solve the question without Pavel's method, cross the direction of the line with the vector formed by the given point and a point you found on the line. Now cross that result with the line direction to get a new vector. Dot that vector with the original point and again with a point on the line. Take the difference, and divide by the length of the vector.

Resources