Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix HalfEdge.prev() #703

Merged
merged 2 commits into from
Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ protected HalfEdge createEdge(Coordinate orig)
return new HalfEdge(orig);
}

/**
* Creates a HalfEge pair, using the HalfEdge type of the graph subclass.
*
* @param p0
* @param p1
* @return
*/
private HalfEdge create(Coordinate p0, Coordinate p1)
{
HalfEdge e0 = createEdge(p0);
Expand Down Expand Up @@ -136,6 +143,12 @@ private HalfEdge insert(Coordinate orig, Coordinate dest, HalfEdge eAdj) {
return e;
}

/**
* Gets all {@link HalfEdge}s in the graph.
* Both edges of edge pairs are included.
*
* @return a collection of the graph edges
*/
public Collection getVertexEdges()
{
return vertexMap.values();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,30 @@ public HalfEdge next()
* Gets the previous edge CW around the origin
* vertex of this edge,
* with that vertex being its destination.
* <p>
* It is always true that <code>e.next().prev() == e</code>
* <p>
* Note that this requires a scan of the origin edges,
* so may not be efficient for some uses.
*
* @return the previous edge CW around the origin vertex
*/
public HalfEdge prev() {
return sym.next().sym;
HalfEdge curr = this;
HalfEdge prev = this;
do {
prev = curr;
curr = curr.oNext();
} while (curr != this);
return prev.sym;
}

/**
* Gets the next edge CCW around the origin of this edge,
* with the same origin.
* If the origin vertex has degree 1 then this is the edge itself.
* <p>
* <code>e.oNext()</code> is equal to <code>e.sym().next()</code>
*
* @return the next edge around the origin
*/
Expand Down Expand Up @@ -467,6 +480,7 @@ public int degree() {

/**
* Finds the first node previous to this edge, if any.
* A node has degree <> 2.
* If no such node exists (i.e. the edge is part of a ring)
* then null is returned.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

package org.locationtech.jts.edgegraph;

import java.util.Collection;
import java.util.List;

import org.locationtech.jts.geom.Coordinate;
Expand All @@ -23,11 +24,11 @@


public class EdgeGraphTest extends TestCase {

public static void main(String args[]) {
TestRunner.run(EdgeGraphTest.class);
}


public EdgeGraphTest(String name) { super(name); }

public void testNode() throws Exception
Expand All @@ -39,8 +40,40 @@ public void testNode() throws Exception
});
checkNodeValid(graph, new Coordinate(0, 0), new Coordinate(1, 0));
checkEdge(graph, new Coordinate(0, 0), new Coordinate(1, 0));

checkNextPrev(graph);

checkNext(graph, 1, 0, 0, 0, 0, 1);
checkNext(graph, 0, 1, 0, 0, -1, 0);
checkNext(graph, -1, 0, 0, 0, 1, 0);

checkNextPrev(graph, 1, 0, 0, 0);
checkNextPrev(graph, 0, 1, 0, 0);
checkNextPrev(graph, -1, 0, 0, 0);

assertTrue( findEdge(graph, 0, 0, 1, 0).degree() == 3 );
}

public void testRingGraph() throws Exception {
EdgeGraph graph = build("MULTILINESTRING ((10 10, 10 90), (10 90, 90 90), (90 90, 90 10), (90 10, 10 10))");
HalfEdge e = findEdge(graph, 10, 10, 10, 90);
HalfEdge eNext = findEdge(graph, 10, 90, 90, 90);
assertTrue(e.next() == eNext);
assertTrue(eNext.prev() == e);

HalfEdge eSym = findEdge(graph, 10, 90, 10, 10);
assertTrue(e.sym() == eSym);
assertTrue(e.orig().equals2D(new Coordinate(10, 10)));
assertTrue(e.dest().equals2D(new Coordinate(10, 90)));

checkNextPrev(graph);
}

public void testSingleEdgeGraph() throws Exception {
EdgeGraph graph = build("LINESTRING (10 10, 20 20)");
checkNextPrev(graph);
}

/**
* This test produced an error using the original buggy sorting algorithm
* (in {@link HalfEdge#insert(HalfEdge)}).
Expand All @@ -61,7 +94,8 @@ public void testCCWAfterInserts2() {
checkNodeValid(e1);
}


//==================================================

private void checkEdgeRing(EdgeGraph graph, Coordinate p,
Coordinate[] dest) {
HalfEdge e = graph.findEdge(p, dest[0]);
Expand Down Expand Up @@ -91,6 +125,31 @@ private void checkNodeValid(HalfEdge e) {
assertTrue("Found non-sorted edges around node " + e, isNodeValid);
}

private void checkNextPrev(EdgeGraph graph) {
Collection<HalfEdge> edges = graph.getVertexEdges();
for (HalfEdge e: edges) {
assertTrue(e.next().prev() == e);
}
}



private void checkNext(EdgeGraph graph, double x1, double y1, double x2, double y2, double x3, double y3) {
HalfEdge e1 = findEdge(graph, x1, y1, x2, y2);
HalfEdge e2 = findEdge(graph, x2, y2, x3, y3);
assertTrue(e1.next() == e2);
assertTrue(e2.prev() == e1);
}

private void checkNextPrev(EdgeGraph graph, double x1, double y1, double x2, double y2) {
HalfEdge e = findEdge(graph, x1, y1, x2, y2);
assertTrue(e.next().prev() == e);
}

private HalfEdge findEdge(EdgeGraph graph, double x1, double y1, double x2, double y2) {
return graph.findEdge(new Coordinate(x1, y1), new Coordinate(x2, y2));
}

private EdgeGraph build(String wkt) throws ParseException {
return build(new String[] { wkt });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ public void testStar() {
checkNext( e2, e2.symOE() );
checkNext( e3, e3.symOE() );

checkPrev( e1, e3.symOE() );
checkPrev( e2, e1.symOE() );
checkPrev( e3, e2.symOE() );
checkPrev( e1, e2.symOE() );
checkPrev( e2, e3.symOE() );
checkPrev( e3, e1.symOE() );
}

/**
Expand Down