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.
Related
Multiple points on a 2D plane are given. They represent a window frame of mostly rectangular form with some possible variations. The points which are part of each side are not guaranteed to form a perfect line. Each side of the window should be measured.
A rotating electronic device attached to a window measures the distance in all directions providing a 360 degree measurements. By using the rotation angle and the distance, a set of points are plotted on a 2D coordinate system. So far so good.
Now comes the harder part. The measured window frame could have some variations. The points should be converted to straight lines and the length of each line should be measured.
I imagine that the following steps are required:
Group the different points into straights lines. This means approximating each line “between” the points that form it.
Drawing those lines, getting rid of the separate points used to construct the lines.
Find the points where each two lines intersect.
Measure the distance between those points. However not all distances between all points are interesting. For example diagonals within a frame are irrelevant.
Any Java libraries dealing with geometry that could solve the problem are acceptable. I will write the solution in Kotlin/Java, but any algorithmic insights or code examples and ideas in any other languages or pseudo code are welcome.
Thank you in advance!
New Image
I would solve this in 2 stages:
Data cleaning: round the location (X, Y) of each point to its nearest multiple of N (vary N for varying degrees of precision)
Apply the gift-wrapping algorithm (also known as Jarvis March)
You now have only those points that are not co-linear, and the lines between them, and the order in which they need to be traversed to form the perimeter.
Iterate over the points in order, take point Px and P(x+1), and calculate the distance between them.
I am trying to extract horizontal lines from a set of 2D points generated from the photo of the model of a human torso:
The points "mostly" form horizontal(ish) lines in a more or less regular way, but with possible gaps/missing-points:
There can be regions where the lines deform a bit:
And regions with background noise:
Of course I would need to tune things so I exclude those parts with defects. What I am looking for with this question is a suggested algorithm to find lines where they are well-behaved, filling eventual gaps and avoiding eventual noise, and also terminating the lines properly upon some discontinuity condition.
I believe there could be some optimizing or voting "flood fill" variant that would score line candidates and yield only well-formed lines, but I am not experienced with this and cannot figure anything by myself.
This dataset is in a gist here, and it is important to note that X coordinates are integers, so points are aligned vertically. The Y coordinates though are decimal numbers.
I would start by finding the nearest neighbor of every dot, then the second nearest neighbor on the other side (I mean only considering the dots in the half plane opposite to the first neighbor).
If the distance to the second neighbor exceeds twice the distance to the first, ignore it.
Just doing that, I bet that you will reconstruct a great deal of the curves, with gaps left unfilled.
By estimating the local curvature along the curve (f.i. by computing the circumscribed circle of three dots, taking every other dot, you can discard noisy portions.
Then to fill the gaps, you can detect the curve endpoints and look for the nearest endpoint in an angle around the extrapolated direction.
First step in the processing:
These are integral curves to the vector field representing the direction pattern.
So maybe start by finding for each point the slope vector, the predominant direction, by taking points from the neighborhood and fitting a line with LS or performing a PCA. Increasing the neighborhood radius should allow to deal with the data irregularities thereby picking up a greater-scale slope trend instead of a local noise.
If you decide to do this, could you post here the slope field you find, so instead of points could we see some tangents?
The problem I am trying to solve is:
Given a set of M points on a plane where circles can be centered and a set of N line segments which need to be covered by the circles, find the minimum area circle cover for the line segments. That is, find the radii of the circles and the centers (chosen from the M points) such that all the N line segments are covered and the total area of the circles is minimized.
Note that a line segment is covered if no part of it is OUTSIDE a circle.
Any pointers to papers or code or approximation algorithms would be great.
Edit: Just realized that the original approach (moved to the end) probably doesn't cover the case where a line segment is best covered by multiple circles very well. So I think it's better to iterate points instead of line segments, cutting the line segments down at the circle boundaries:
Find the "worst" point, i.e. the point requiring the largest additional circle area for its best circle center option with the corresponding line segment at least partially in the circle. Construct / extend the corresponding circle.
Remove fully covered line segments from the set and cut partially covered segments at the circle boundary.
Iterate until no more line segments remain.
The main idea is to keep doing what's necessary in any case. How are overlapping circles counted? Do the areas add up, or are they merged? When going back to step one in later iterations, some kind of cost heuristics will probably be able to improve the result...
The original suggestion was:
Find the "worst" line segment, i.e. the line segment requiring the largest circle for any of the circle center options and construct the corresponding circle.
Remove covered line segments from the set.
Iterate until no more line segments remain.
I just released some code to implement the suggested algorithm here:
https://github.com/usnistgov/esc-antenna-cover
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.
I have map (openstreetmap project) with many buildings. Each building is a polygon. How can I make saddle roof parts polygons for every building outline?
Algorithm should transform one polygon in 2D to set of polygons in 2D (or 3D).
Reason for this transformation is visualization - better rendering isometric view.
For example (shading isn't important):
alt text http://www.freeimagehosting.net/uploads/0168cec03a.png
Thanks
Main part (like 90%) of what you are looking for is called "skeleton". Take a look here, at the figure called "Other examples". This page is from a manual of a computer graphics library, so you'll find there a general description, and links to the (free) code.
Isn't this just what you get with a 4-neighbor watershed algorithm, plus marking all edges that are local extrema along the line perpendicular to the direction of fastest ascent? (The shading would need to be added somehow, of course, but wouldn't this give you the position of the roof peaks and angles?)
Your examples seem to assume that all roof slopes are the same. The additional lines (when seen directly from above) are then the lines of equal distance from the edges. These can be constructed by taking the angle bisector between two edges.
The algorithm would look like this:
Start with any two neighbouring edges.
Add a line along their angle bisector.
Take the next neighbouring edge.
Add a line along this angle bisector.
Where two new lines meet, mark a new vertex, and clip the lines.
From this vertex, add a line along the angle bisector of the two outer edges where the two lines originated.
Take the next edge, etc..
Take care to correctly clip the new lines and manage the new vertices.