I am currently struggling with the current problem:
I have defined n lines (with SymPy). In the end, they shall describe a polygon. (See target in image)
Now I want to find the "mid" or "center" line to those polygons.
My first thought was to put a circle between the lines.
But: How does the algorithm know which lines are the opposing ones to put the "ball" between?
So basically I can define a line to start. Now I am searching for the line with the nearest distance and so on. But this solution does not seem generic enough to me to able to capture all polygon types.
How can I write my script so that it is able to create a polygon center line(or lines in example case e) ) from a list of sympy lines?
I also ready something about "skeletonization", but this seems to be more suited for pixel images.
Thanks a lot!
Best regards
Benny
Example cases
I'm not sure how general your solution must be, but here's a technique that should work to find the mid line for the three use-cases in the link:
Assume one blue line is defined by the points (B1, B2) and the other blue line is defined by points (D1, D2). I would create two new lines: one connecting B1 and D1, and the other connecting B2 and D2. Using SymPy it should be easy to determine the midpoint of a line segment. The desired red line would be the line connecting the midpoint of the (B1, D1) segment and the (B2, D2) segment.
This should work without modifications for (a) and (b); the (c) case can be solved with the same idea, if you remember to handle each pair of line segments separately. Enjoy!
Related
I've been trying to find a way to replicate the following network graph format in R using DiagrammeR/GraphViz, but without success (ignore the thick black arrow on N1): https://i.stack.imgur.com/oHpQz.png
The graph is a directed graph and each edge in a certain direction either ends with an arrowhead (-->) if the edge value is positive, or a circle/odot (--o) if the edge value is negative. Between a pair of nodes (ex. N1 -- A1), there can be an edge N1 --> A1 and an edge A1 --o N1, and these need to be concentrated so that the two edges look like one line with an arrowhead on one end and a circlehead on the opposite end (like this: o--->). These cannot be parallel or look like two edges ideally.
Another requirement is that the nodes have to be in very specific positions and remain there throughout model simulations where edges might change. From what I have tried and the documentation I have read, this is not possible to do in DOT format, but is possible in neato format.
This is where I get a problem. In neato, I can align the nodes exactly where I want them by defining their x,y positions. However, when I use concentrate = true to create the o---> edge from two otherwise parallel edges, only one type of arrowhead remains. So an edge that's supposed to look like o---> ends up looking like ---> or o---.
This is not a problem in DOT format as concentrate = true does what I want it to do, but in DOT I cannot assign exact node positions. I have tried getting around this using node ranks but without much luck. It seems to stack nodes I want in different ranks within the same rank. As well, concentrate = true doesn't seem to work for edges between nodes within the same rank, as it leaves them as two separate curved edges ---> and o--- without concentrating them.
The reason why I need this to work is because I'm running model simulations where the edges change, and I need to generate hundreds of such graphs. For easy comparison, the nodes need to stay in the same place for consistency.
This is the closest I could come up with using neato format (nodes are positioned the way I want but it's not showing the proper o---> for all the black edges minus self-edges; red edges are true one-way links): https://i.stack.imgur.com/YJBY7.jpg
If only the edges showed up as the proper o---> format, this would be perfect for my needs. If you know of any way to fix this issue using DiagrammeR/GraphViz, or even another program, I would be so grateful. Thanks!
You probably don't need concentrate. Look at arrowtail and dir (https://www.graphviz.org/doc/info/attrs.html#d:arrowtail and https://www.graphviz.org/doc/info/attrs.html#d:dir) and neato -n
digraph c {
graph[label="can neato do the work?"]
node[shape=circle]
a [pos="100,100"]
b [pos="200,100"]
c [pos="300,100"]
a->b [dir=both arrowtail=odot]
c->c [dir=both arrowtail=odot arrowhead=none]
}
Giving:
Challenge:
We have two lines.
Blue line passes through points : (20,100), (25,44.44), (30,30), (35,20), (40,0), (45,0), (50,0), (55,0), (60,0)
Pink line passes through points : (20,00), (25,0), (30,0), (35,0), (40,20), (45,33.33), (50,64.44), (55,100), (60,100)
Without any manual intervention, I want to know the point where they intersect. For example, the point of intersection as shown in figure is (37.5,10)
Remember: The only input of the program is set of points of two lines. Output needed is intersection point of both the line.
Things that did not work out:
I tried to find library of Python that can generate intersection point of two lines(both passing through more than two points). Couldn't find it.
I tried to find a mathematical equation generator for lines passing through more than two points. Then I thought I'll be able to find the intersection of those two equations. Got very complex with lots of polynomial equations!
Most of the places I searched in internet were able to give me intersection of two straight lines that passed through two points only. However as seen in the above image, the both the line passes through about 9 points.
Correct solution:
Well, call it a bummer or any but the solution wasn't as complex as I thought.
Now if you carefully look at the image, you can interpret it in this way:
Instead of calling it a line that passes from lots of points and not just two points, call it a line that is passing through two points. Then it is passing through another two points. Then another two points.. so on..
There are many solutions available online for finding intersection of lines that passes through 2 points. The problem here was only because of the interpretation that both the lines are passing through N number of points (N>2).
Hence, the answer is calculated this way
Step 1: Check for intersection of line1 with first two points [(20,100),(25,44.44)] and line2 with first two points[(20,0.0),(25,0.0)]
Step 2: Check for intersection of line1 with next two points [(25,44.44),(30,30)] and line2 with first two points[(25,0.0),(30,0)]
Step 3: Repeat this process for the whole loop of points till the last point is reached.
Output: The program was able to yield (37.5,10) correctly!
PS: I can share the code of this if need be.
I am creating a line from point shapefile which is auto generated. First time when I create that line in ArcGIS, I got a line like this because the points are not in a order:
after that I ordered the points according to it's location and got a line like this:
But unable to create a line like this:
Please give me any solution to fix this in ArcGIS or R programming. If you need the shapefile I can provide you.
I think there is no bullet proof way to restore the line, as same dataset can obviously represent different lines, so you would need to use some heuristics to do this. What Rafael described is very good top-bottom heuristics if you can reliably detect start and end points.
Another heuristics could be a bottom-up process to stitch nearby segments into a line. Find nearby points for every point, sort and connect the two nearest points. Continue this process, making sure each point has at most two connections, and that there are no loops.
A simpler approach that might just work if the line follows in general some direction is your idea of sorting points. But instead of ordering by x or y coordinate, find a linear approximation of these points, project each point to this straight line, and sort using the coordinate of the projection.
One way to go about this would be to treat it as a graph problem.
Create a weighted fully connected graph where the nodes are the points and the edge weight distance between its endpoints. Heuristically identify the “starting” and “ending” points of the line (for example, pick the bottom-leftmost point as start and top-rightmost and end).
Then you can use a shortest path algorithm to generate the order in which you connect the points.
I have the two points p1 and p2 and the line l (black). The line is made of 100+ internal points arranged in an array starting from p1 and ending in p2.
Now, I would like to convert the curved line to a "straight" line like the red line on the above illustration. I am, however, a little unsure how to do this.
So far, my idea is to iterate the line with a fixed distance (e.g. take all points from start and 100 pixels forward), calculate the curve of the line, if it exceeds a threshold, make the straigt line change direction, then iterate the next part and so on. I'm not sure this would work as intended.
Another idea would to make a greedy algorith trying to minimize the distance between the black and red line. This could, however, result in small steps which I would like to avoid. The steps might be avoided by making turns costly.
Are there any algorithms about this particular problem, or how would you solve it?
Search for the phrase polygonal chain simplification and you'll see there is quite a literature on this topic.
Here is one reference that could lead you to others:
Buzer, Lilian. "Optimal simplification of polygonal chains for subpixel-accurate rendering." Computational Geometry 42.1 (2009): 45-59.
I have thought some time about writing a program that tells me if three circles with given diameters can fit inside a triangle with given side lengths without overlapping (touching is ok) each other.
How would one think about doing that?
I would try to find some way to enumerate the possible configurations for the three circles, and then test each configuration until one is found where the three circles fit, or until all configurations have been tested and rejected.
(In what follows I am assuming that each circle is known to fit in the triangle by itself. Obviously if any circle fails to fit by itself then it fails to fit in any configuration of three circles.)
Configuration (1) involves putting a circle in each corner of the triangle. (This is the configuration that everyone spotted.)
There are six ways to arrange the circles, and for each arrangement it sufficient to check whether the circles will fit pairwise:
The distance AS₁ is r₁/tan(½α), the distance S₂B is r₂/tan(½β), and the distance S₁S₂ is √((r₁ + r₂)² − (r₁ − r₂)²) = 2√r₁r₂
The circles fit if AS₁ + S₁S₂ + S₂B ≤ AB.
In configuration (2) we place two circles into two of the corners of the triangle, and the third circle between these two and one of the two edges that's not touching both circles:
Figuring out whether these will fit is a bit more complex:
To find the length AS₁ we have to walk round the triangle from corner C via the point T. I'll leave the details of this as an exercise.
There are eighteen ways to arrange the circles into this configuration.
Is there a configuration (3)? I looked but couldn't find one that couldn't be turned into one of the two I gave. For example, if all three circles touch the same side then there's always room to swap the middle circle over to the opposite side, getting configuration (2). However, enumeration of geometric configurations is always tricky and I could easily have missed one.
Just a guess: your problem could be related to that of Appolonius's circles.
I ran into it while trying to fit recursively 3 circles within a 4th one without any intersection for some fractal animation, so it may be worth a try.
You'll find it explained in length at Wolfram (this problem was solved only in 1968):
http://mathworld.wolfram.com/ApolloniusProblem.html
this seems to be a tough and interesting problem. Through the solution of the Marble Problem (related to Malfatti's Circles) by Los and Zalgaller in 1994, it might be possible for you to tediously extract a necessary condition for existence of a configuration of three non-overlapping circles with given radii inside a triangle with prescribed side lengths. If you can place them inside the triangle, the sum of their areas will be at most the maximal possible area for three triangles inside a circle. The Marble Problem is the problem of determining the maximal area of three non-overlapping circles inside a given triangle. Right now, I can't see that this is also sufficient.
Perhaps it would be worth, as a start, to introduce an ε to the problem and then look for an algortihm that in a finite number of steps, could determine if a configuration which is at most "bad by ε" (defined in some sensible way) exists.
Some of the World's top mathematicians participate regularly at stackoverflow's sibling,
mathoverflow.org, so you could try posting this problem over there.
Thanks for posting this.
I think it's sufficient to try all 6 possible permutations (A1 B2 C3, A2 B1 C3, A1 B3 C2, A3 B1 C2, A2 B3 C1, A3 B2 C1). If a circle isn't tangent to two edges of the triangle, then it's placement is suboptimal in some sense and you could make more space for the other two by sliding it into a corner. If it's possible to stick three circles in a triangle without them overlapping then it's probably possible to slide them into the corners (for the case in which they're all jammed against the edges, lift them all up together and rotate by 60 degrees). Of course, this isn't a rigorous proof, but I'm pretty sure it works.
Furthermore, I imagine the solution will always be to place the largest circles at the widest angles, because those are the ones that could potentially take up the most central triangle space.