3

O(nlogn) algorithm

I am trying to solve the problem shown in the image attached. I got the divide part, where you would recursively divide the line sets into halves and the lines with the smallest and largest slope would be visible.

I don't know how to do the merge part though and I'm not understanding it.

Intuitively, at first, I'd think that all lines would be visible eventually if there are no three lines that intersect at one point.

As well, the conquer part is when I would take out invisible lines... from what I understand, there shouldn't be any lines taken out before the conquer phase.

If anyone can explain for those of us that has a bit of a slower brain, I'd be very thankful! :)

rjgupta21
  • 182
  • 4
  • 17
  • without illustrative image we can only guess ... unseen lines removal in computer gfx is usually done by computing the surface normal (if mesh is convex) . Concave meshes are subdivide to convex meshes prior to this. There may be other algorithms out there exploiting something known about the case for which it is used but without more info is hard to say to what is you example refering to. If your mesh is solid (not just wire-frame) then you can use Z-sorting or Z-Buffering but I guess that is not what you want to hear – Spektre Oct 08 '15 at 11:16

1 Answers1

1

Consider a 3 line example. You have 2 options. a) only 2 lines are visible b) all 3 lines are visible.

So you need to determine if the middle one is visible or not. To do this you can compute the intersection point of the outer 2 lines (call it A). If A is above the the middle line then the middle one is hidden, if it's below then it's visible (draw the two figure and it will be obvious).

To determine if the point is above or below substitue it's coordinates in the line equation (y = ax + b). If y > ax + b then the point is above the line, if y < ax + b the point is below and if y = ax + b the point is on the line (shouldn't happen according to the problem).

To solve your problem I would just take the lines in order of the slope and try to add them to the solution. Every time you add a new line check if the previous line is still visible and remove it if it's not (repeat as many times as needed, since the new line might hide more than just one previous line).

If you insist on doing merges you need to apply this logic on the merge line to figure out how many lines you remove from the middle.

Sorin
  • 11,863
  • 22
  • 26
  • This will take O(n^2) runtime, if I am not wrong. Can we do it in nlgn? – Riken Shah Sep 30 '17 at 19:50
  • It's NlogN because of the sorting. The adding and removing is O(N) because you only add a line once and maybe later you remove it (but only once). – Sorin Oct 05 '17 at 09:58
  • Every time you add a new line and try to check if it is visible, you are checking it with all other lines, which will take O(n) time. Thus, the whole algorithm will take O(n^2) since you are doing it for all n lines. – ganjim Oct 04 '20 at 06:07
  • @MoGanji You are only partially correct. One line can check against all the others and result in O(N), however that can't happen for every line. One way to think about it is this, every line you add once O(1). For every line you have a bunch of checks that fail and remove a line (potentially O(N) ) and one check that passes and you stop the iteration O(1). So now to sum every thing up, we add O(N) lines, we have O(N) checks that pass and stop the iteration and we would have O(N^2) line removals. But the last one can't happen since you can only remove O(N) lines since we only have a total of N – Sorin Oct 05 '20 at 07:57
  • @Sorin That was quite a good explanation, however, how can you be sure that you are removing a line in every iteration? what if the iterations end up removing no lines? in this case, it is possible to have O(n^2), right? – ganjim Oct 06 '20 at 08:43
  • @MoGanji I'm not claiming that I'm removing a line each iteration. Say we count the number of lines removed each time `r1, r2, r3, ... rn`. Each `rX` can be anywhere between 0 and N. What I'm claiming is that `r1+r2+r3+..+rn <= N`. That is because once you remove a line it is gone and we only have N lines. – Sorin Oct 06 '20 at 15:53
  • @Sorin So I think I did not understand your solution correctly, since I'm imagining a case where no line is removed at all(all lines are visible), in this case, when adding a line, you will have to check it against all previously added lines, as a result, you will need O(n^2) for that. If you can possibly explain your solution more elaborately I would be grateful. – ganjim Oct 07 '20 at 08:56
  • @MoGanji When checking, you stop when the previous line is visible (and you don't remove it). You can demonstrate that for any line before, because you've sorted by slope, if the line would be hidden by your most recent line, it would also be hidden by the line before it (the one you stopped iterating on). That means it should have been eliminated by the previous line. So there's no point in checking them all since all previous lines are visible. Take some examples on a piece of paper, it should be clear. – Sorin Oct 07 '20 at 10:02
  • @Sorin What about the intercepts? consider these four lines sorted by slope for example: `L1=-x; L2=1; L3=x+1;L4=2x+6` in this case, the second line will be visible until the fourth line removes it, however, in your algorithm when adding the fourth line, we only check the third line and pass, thus, fail to remove the second line which is not visible after all – ganjim Oct 07 '20 at 10:20
  • @MoGanji I think you got some sign wrong somewhere. The intersection between L2 and L4 is (-2.5, 1), plugging it into the L3 formula we get 1 > -2.5+1 , so the intersection point is above the L3 line, so L3 should be removed. Since we've removed a line we continue the iteration. We then proceed to check L2, by doing the intesection between L1 and L4. It should also result in removing the L2 line. https://www.desmos.com/calculator/qmgr2fn26g – Sorin Oct 08 '20 at 07:51
  • @Sorin Sorry, I meant to bring an example where for three lines L1, L2, L3 all three are visible, but with adding the fourth line, the L2 gets hidden. Which I realized that this case is impossible, since if L4 wants to remove L2, then the intersection of L3 and L4 will be after the intersection of L2 and L4, and since the slope of L4 > slope of L3, this means that L4 will remove L3 too. So my counterexample case was invalid somehow. I can't think of any other special case, however, I did not understand why this works correctly. Thank you so much for being patient and your explanations. – ganjim Oct 09 '20 at 06:57