I have a simple programming problem related to geometry! I can solve it using pencil and paper (in visual mode!!), however I am not sure if I can program it. I don't need the code itself, but a pseudo code or an idea to implement.
The are 4 points in a line, whom position are given. Each point requires a minimum space around himself, which is given after the position of the point. We want to find the minimum (in length) line segment, which can satisfy all requirements above. In other words I need minimum spanning line over these points with minimum space around requirements.
Example:
$p_i$: (x, L), where x denotes the position (a real number), and L denotes the minimum space requirement around x.
p1: (1,1)
p2: (2,1)
p3: (5,1)
p4: (7,2)
Graphical representation:
as it is shown the result is a line segment from 1 to 7 with length 6.
Another example:
p1: (2,1)
p2: (3,2)
p3: (4,1.5)
p4: (6.5,0.5)
the result (the green line below) is a line segment from 2 to 6.5 (length: 4.5)
The length of optimal result is always more than max(x_i)-min(x_i) i=1,2,3,4
It is also easy that always there is an optimal solution where one end point of it is matched to an x_i, i.e. you can roll the spanning optimal result to be matched with a point, for example x_1.
Sweep from $-\infty$ to $+\infty$. Start x_1 and span it over its right margin. additionally start all other points you can (i.e. points that their left margin have been started). In other words start the first point as late as possible, after it, start all other points as soon as possible.
Finally, if there is a point x_i, where its left margin has been started before x_1, call this diference as diff_i. Add all diff_i to all x_i s and find all segments out of the final point of the results (i.e if (x_i+diff_i>current_end_position then current_end_position=x_i+diff_i.
Thanks for your comments.
Related
I'm trying to draw a path from one foreignObject to another.
I'd like the path to be oriented / set according to the centre of each object, but only start some distance away from the object. For example, here are straight-lined paths from one object to two different objects: notice that the starting point for the paths is not the same; rather, it has been adjusted to lie on the line connecting the two objects.
If the path is a straight line, this is easy enough to achieve: simply start and end
the path at a displacement of Δr along the straight line defined by the centre points of the objects.
However, I'm not sure how one would achieve this, in the case of a Bezier curve (quadratic or cubic).
If it were possible to make part of the path transparent (i.e. set the stroke colour for different parts of the path), then one could just use the centre points and set the the first Δs px to transparent; however, I'm not aware of any way of doing this.
Alternatively, if it were possible to set the start and end points of a path independently of the points used to compute the path, this would address all cases (linear, Bézier quadratic or cubic).
Another option might be to use the dash-array property, but this would require knowing the length of the path. e.g. if the path length is S, then setting the dash-array to x-calc(S-2x)-x would also achieve the desired result.
Is there any way of achieving this programmatically?
I don't mind legwork, so even just pointers in the right direction would be appreciated.
Here's an idea: use de Casteljau algorithm twice to trim off the beginning and the end portions of your curve.
Say you were asked to evaluate a cubic Bézier curve defined by the control points C_{0,0}, C_{1,0}, C_{2,0} and C_{3,0} at a particular parameter t between 0 and 1. (I assume that the parameter interval of the curve is [0,1] and I give the control points such strange names in the anticipation of the following. Have a look at the Wikipedia article if you work with a curve degree different from 3.)
You would proceed as follows:
for j = 1, ..., 3
for i = 0, ..., 3 - j
C_{i, j} = (1 - t) * C_{i, j-1} + t * C_{i+1, j-1}
The point C_{0, 3} is the value of your curve at the parameter value t. The whole thing is much easier to understand with a picture (I took t=0.5):
However, the algorithm gives you more information. For instance, the control points C_{0,0}, C_{0,1}, C_{0,2} and C_{0,3} are the control polygon a curve which is equal to your curve restricted to the interval [0, t]; similarly, C_{0,3}, C_{1,2}, C_{2,1} and C_{3,0} give you a Bézier curve equal to your curve restricted to [t, 1]. This means that you can use de Casteljau algorithm to divide your curve in two at a prescribed interval.
In your case, you would:
Start with the curve you show in the bottom picture.
Use de Casteljau algorithm to split your curve at a parameter t_0 close to 0 (I would start with t_0 = 0.1 and see what happens).
Throw away the part defined on [0, t_0] and keep only that defined on [t_0, 1].
Take a parameter t_1 close to 1 and split the remaining part from 3.
Keep the beginning and throw away the (short) end.
Note that this way you will be splitting you curve according to parameter values and not based on its length. If your curves are similar in shape, this is not a problem but if they would differ significantly, you might have to invest some effort at finding suitable values of t_0 and t_1 programmatically.
Another issue is the choice of t_1. I suppose that due to symmetry, you would want to split your curve into [0, t_0], [t_0, 1 - t_0], [1 - t_0, 1]. Taking t_2 = 1 - t_1 would not do, because t_2 refers to the parameter interval of the result of step 3 and that is again [0, 1]! Instead, you would need something like t_2 = (1 - t_1)^2.
A basic solution using layers:
Layer 1: paths;
Layer 2: elements coloured the same as the background which are slightly larger than the elements layered on top of them (for the emoji, I used circles, for text, I used the same text with a larger pt-size);
Layer 3: the elements themselves.
Pros & Cons
Pros:
quick;
easy;
Cons:
can't use markers (because they are masked by the background-coloured objects);
may require some tinkering to find the most appropriate type of background element;
Here is a screenshot of a sample output:
Let's assume I have a polygon and I have computed all of its self-intersections. How do I determine whether a specific edge is inside or outside according to the nonzero fill rule? By "outside edge" I mean an edge which lies between a filled region and a non-filled region.
Example:
On the left is an example polygon, filled according to the nonzero fill rule. On the right is the same polygon with its outside edges highlighted in red. I'm looking for an algorithm that, given the edges of the polygon and their intersections with each other, can mark each of the edges as either outside or inside.
Preferably, the solution should generalize to paths that are composed of e.g. Bezier curves.
[EDIT] two more examples to consider:
I've noticed that the "outside edge" that is enclosed within the shape must cross an even number of intersections before they get to the outside. The "non-outside edges" that are enclosed must cross an odd number of intersections.
You might try an algorithm like this
isOutside = true
edge = find first outside edge*
edge.IsOutside = isOutside
while (not got back to start) {
edge = next
if (gone over intersection)
isOutside = !isOutside
edge.IsOutside = isOutside
}
For example:
*I think that you can always find an outside edge by trying each line in turn: try extending it infinitely - if it does not cross another line then it should be on the outside. This seems intuitively true but I wonder if there are some pathological cases where you cannot find a start line using this rule. Using this method of finding the first line will not work with curves.
I think, you problem can be solved in two steps.
A triangulation of a source polygon with algorithm that supports self-intersecting polygons. Good start is Seidel algorithm. The section 5.2 of the linked PDF document describes self-intersecting polygons.
A merge triangles into the single polygon with algorithm that supports holes, i.e. Weiler-Atherton algorithm. This algorithm can be used for both the clipping and the merging, so you need it's "merging" case. Maybe you can simplify the algorithm, cause triangles form first step are not intersecting.
I realized this can be determined in a fairly simple way, using a slight modification of the standard routine that computes the winding number. It is conceptually similar to evaluating the winding both immediately to the left and immediately to the right of the target edge. Here is the algorithm for arbitrary curves, not just line segments:
Pick a point on the target segment. Ensure the Y derivative at that point is nonzero.
Subdivide the target segment at the Y roots of its derivative. In the next point, ignore the portion of the segment that contains the point you picked in step 1.
Determine the winding number at the point picked in 1. This can be done by casting a ray in the +X direction and seeing what intersects it, and in what direction. Intersections at points where Y component of derivative is positive are counted as +1. While doing this, ignore the Y-monotonic portion that contains the point you picked in step 1.
If the winding number is 0, we are done - this is definitely an outside edge. If it is nonzero and different than -1, 0 or 1, we are done - this is definitely an inside edge.
Inspect the derivative at the point picked in step 1. If intersection of the ray with that point would be counted as -1 and the winding number obtained in step 3 is +1, this is an outside edge; similarly for +1/-1 case. Otherwise this is an inside edge.
In essence, we are checking whether intersection of the ray with the target segment changes the winding number between zero and non-zero.
I'd suggest what I feel is a simpler implementation of your solution that has worked for me:
1. Pick ANY point on the target segment. (I arbitrarily pick the midpoint.)
2. Construct a ray from that point normal to the segment. (I use a left normal ray for a CW polygon and a right normal ray for a CCW polygon.)
3. Count the intersections of the ray with the polygon, ignoring the target segment itself. Here you can chose a NonZero winding rule [decrement for polygon segments crossing to the left (CCW) and increment for a crossing to the right (CW); where an inside edge yields a zero count] or an EvenOdd rule [count all crossings where an inside edge yields an odd count]. For line segments, crossing direction is determined with a simple left-or-right test for its start and end points. For arcs and curves it can be done with tangents at the intersection, an exercise for the reader.
My purpose for this analysis is to divide a self-intersecting polygon into an equivalent set of not self-intersecting polygons. To that end, it's useful to likewise analyze the ray in the opposite direction and sense if the original polygon would be filled there or not. This results in an inside/outside determination for BOTH sides of the segment, yielding four possible states. I suspect an OUTSIDE-OUTSIDE state might be valid only for a non-closed polygon, but for this analysis it might be desirable to temporarily close it. Segments with the same state can be collected into non-intersecting polygons by tracing their shared intersections. In some cases, such as with a pure fill, you might even decide to eliminate INSIDE-INSIDE polygons as redundant since they fill an already-filled space.
And thanks for your original solution!!
I have a maze described by walls as line segments (no given order). Given a point, I need to determine whether its inside the maze or no. Everything is in the Cartezian plane(no discretization).
My idea is to transform the problem as follows:
Given some line segments in the plane, find all polygons with vertices in the endpoints of the given segments and with sides lying on the segments (you can see in the image below that you can't assume the sides will form a subset of segments).
And then just check: if a point is only inside one polygon, then its inside of the maze, otherwise no.
The solution I have in mind would be: hash endpoints and line intersections, and then look for loops.
Any other suggestions?
Thanks!
(ignore the colors in the image)
It is enough to find boundary (outer) polygon. That can be done by finding one point on the boundary and than traversing from that point by segments in one direction. If there are more possibilities to go than choose 'outer' one. Algorithm can be described:
find boundary point
find first direction to go and go to that point
while current point is different than fist one
find next direction to go
go to next point
First point can be find as point with highest Y coordinate, if there are more like that than one with lowest X among them. We can call it upper-left point.
First direction to go: first point is connected to other points and that points have <= Y coordinate, what means that connection segments are below first point. Choose right-most of them.
Next direction to go: current point is reached by some (incoming) segment, next segment to go is furthest away in positive direction from incoming one, what is same as first segment in clock-wise direction from incoming segment.
I made an OCaml program which draws on a Graphics window the representation of a given l-system using his definition,his commands interpretation and iteration.
The drawing is made using Turtle graphics(the turtle can draw a line,move to a given point and turn for a given angle).
The problem I have is that all the lines have the same size(and this is how it needs to be) and when I draw an L-system if i don't give the right line size the drawing goes out of graphics window as you can see on that picture.
I know I can move the drawing on the left but I always start drawing from the center of the window.What I need help for is how to set the right line size for a given sequence of cammands for example:
I have that list of instructions below :
ACAABAABABACACAACACACACAACAABABACAABAABABACACAACACACACAACAABABACAABAABABACACAACACACACAACAABABACAABAABABACACAACACACACAACAABA.
where A means: Draw a line of "X" size
B : turn π/2
C: turn -π/2.
How can I find the best value for X (size of the line) in order to have a drawing that stays on the graphics window.
The only solution I've found is to start from a given value (Example X=20) and try to draw the l-system with this value, if it goes out then try again with X/2 until it works !
Does anybody have a better idea?
You could do some analysis of the L-system to determine its range, and scale appropriately. However, this is not much different than just drawing it with an arbitrary size (say, 1) seeing how big it is, and scaling (once) to fit the screen (not just X/2 until works). For example, if you draw it with scale=1 and it is 40 units in size, and your screen is 400 units, you know you can draw with scale=10 and still fit. You can also use this first pass to determine XY offset so you can center it.
My idea is to make one pass to evaluate sizes of your labyrinth. Let (W: int) be your width variable. When painter moves West you decrement W and when your painter moves East you incerement W. If m1 is maximal possible value of W and m2 is minimal value (maybe, < 0) of W during process then total width of you diagram is padding + linewidth * (m1-m2)
For example: let's painter initially looks to East.
AAAAABABAAAAAABABA
i.e.
<<<<<.
>.>>>>
During process W will change this way:
AAAAABABAAAAA A B A BA
01234555543210-1-1-1-10
Robot makes 5 steps to East, moves up, and moves 6 steps on West, moves down and returns to start location. In this case m1 = 5 and m2 = -1 and you need canvas of size 5+(-1) multiply line width.
I am working with a Microchip dsPIC33FJ128GP802. It's a small DSP-based microcontroller, and it doesn't have much power (40 million instructions per second). I'm looking for a way to render a convex (i.e. simple) polygon. I am only dealing with 2D shapes, integer math, and set or clear pixels (i.e. 1 bit per pixel.) I already have routines for drawing fast horizontal and vertical lines (writing up to 16 pixels in 88 cycles), so I would like to use a scanline algorithm.
However, all the algorithms I have found seem to depend on division (which takes 18 cycles on this processor) and floating point math (which is emulated in software and so is very slow; it also takes up a lot of ROM), or assume that I have a large amount of memory. I only have 2K left, ~14K is used for graphics RAM of my 16K. So does anyone know of any good, embedded machine algorithms they can point me to with a simple C or pseudocode implementation which I can implement in assembly? Preferably on the 'net, I don't live near any good bookstores with many programming books.
Thanks. :)
EDIT: Clarification, this is a polygon filling algorithm I'm looking for. I can implement a polygon outline algorithm using Bresenham's line drawing algorithm (as Marc B suggests.)
EDIT #2: I wanted to let everyone know I got a basic algorithm up in Python. Here's a link to the code. Public domain code.
http://dl.dropbox.com/u/1134084/bresenham_demos.py
How about Bresenham's Line algorithm? After some setup, it's pure integer math, and can be adapted to draw a polygon by simple iteration of starting points along the polygon edges.
comments followup:
I'll try to draw this in ASCII, but it'll probably look like crud. Bresenham's can be used to draw a filled polygon by picking a starting edge, and iteratively moving a bresenham line across the canvas parallel to that point.
Let's say you've got some points like this:
*(1)
*(3)
*(2)
*(4)
These are numbered in left-right sort priority, so you pick the left-most starting point (1) and decide if you want to go vertically (start 1,2) or horizontally (1,3). That'd probably depend on how your DSP does its display, but let's go with vertical.
So... You use the 1-2 line as your starting bresenham line. You calculate the starting points of your fill lines by using lines 1-3 and 2-4 as your start/end points. Start a bresenham calculation for each, and draw another Bresenham between those two points. Kinda like:
1.1 -> 2.1, then 1.2 -> 2.2, then 1.3 -> 2.3
etc... until you reach the end of either of those lines. In this case, that'd be when the lower starting point reaches (4). At that point, you start iterating up the 4,3 line, until you reach point 3 with both starting points, and you're done.
*-------
\\\\\\\\ *
\\\\\\\\
*-----\\
------- *
Where the dashes are the starting points you calculated along 1-3 and 2-4, and the slashes are the fill lines.
Of course, this only works if the points are properly sorted, and you've got a convex polygon. If it's concave, you'll have to be very careful to not let your fill lines cross over the border, or do some pre-processing and subdivide the original poly into two or more convex ones.
You may want to look at Michael Abrash's articles on Dr Dobbs about polygon fill/raster/etc. It uses fixed-point math
Thomas, if you have a Bresenham line drawing algorithm available, then use it as a basis for further enhancement: divide your polygon to sub-polygons with an horizontal cutting line through every vertex. Then, start tracing the 2 left and right sides of each of these sub-polys, using Bresenham. This way you have the 2 end-points of each scan line in your polygon.
I would start by converting the polygon to a collection of triangles and render those, because triangles are easy to render by scanlines. Although even so there are some details.
Essentially, the draw-triangle sub-procedure will be given a raw triangle and proceed:
Reject degenerate triangles (where two of the three vertices overlap).
Sort the vertices in Y (since there are only three you can hardcode the sorting logic).
Now, at this point you should know that there will be three kinds of triangles: ones with a flat top, ones with a flat bottom, and "general" triangles. You want to handle a general triangle by essentially splitting it into one each of the flat types. This is because you don't want to have an if test every scanline to detect if the slope changed.
To render a flat triangle, you would run two Bresenham algorithms in parallel to iterate the pixels comprising the edges, and use the points they give you as the endpoints of each horizontal scanline.
It may be easier to break the problem into two parts. First, locate/write an algorithm that draws and fills a triangle. Second, write an algorithm that breaks up an arbitrary polygon into triangles (using different combinations of the vertices).
To draw/fill a triangle, use Bresenham's Line Algorithm to simultaneously draw a line between points 0 and 1, and between 1 and 2. For each input point x, draw the pixel if it is equal to or in between the y points generated by the two lines. When you reach one endpoint, continue by using the unfinished side and the side that has not yet been used.
Edit:
To break your convex polygon into triangles, arrange the points in order and call them P1, P2, ... PN. Let P1 be your "root" point, and build triangles using that point and combinations of adjacent points. For example, a pentagon would yield the three triangles P1-P2-P3, P1-P3-P4, and P1-P4-P5. In general, a convex polygon with N sides will decompose into N-2 triangles.