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

originToDirectedEdges does not return edges in clock-wise/sorted order ? #695

Open
SkybuckFlying opened this issue Sep 17, 2022 · 4 comments

Comments

@SkybuckFlying
Copy link
Contributor

SkybuckFlying commented Sep 17, 2022

I was expecting this function/api:

originToDirectedEdges

to return the edges in sorted order, for example clockwise.

But it does not seem to do that ???

Is there a way to fix this, perhaps compute angles and re-sort the array ? I could use some math help here ! ;) :)

"
Provides all of the directed edges from the current H3Index. edges must be of length 6, and the number of directed edges placed in the array may be less than 6. If this is the case, one of the members of the array will be 0.
"

Later I use this function/api to get the destination H3Index:

getDirectedEdgeDestination
"
Returns the destination hexagon from the unidirectional edge H3Index.
"

Additional notes to describe the problem:

The first api call does not sort the edges in clock-wise order... so it seems to be unsorted... this is a problem when trying to visualize the triangles between the centers.

I want to create a triangle from center of hexagon, to center of neighbour hexagon, and then to next neighbour hexagon.
(So these 3 points for a triangle)

The next neighbour hexagon should be in clock-wise order to get a nice triangle.

Otherwise 180 degree triangles could occur and this looks bad.

@SkybuckFlying
Copy link
Contributor Author

OpenGL seems to like counter-clock-wise, well as long as it's in clock-wise or counter-clock-wise order then it should be interexchangeable, but not random order:

https://learnopengl.com/Advanced-OpenGL/Face-culling

@nrabinowitz
Copy link
Collaborator

H3 edges are given in direction order, which is based internally on IJK axes. They don't go around the cell in order. I believe the sequence is consistent, but there may be some vagaries around icosahedron edges (and of course with pentagons).

This snippet from the H3 codebase may be helpful:

/** @brief H3 digit representing ijk+ axes direction.
 * Values will be within the lowest 3 bits of an integer.
 */
typedef enum {
    /** H3 digit in center */
    CENTER_DIGIT = 0,
    /** H3 digit in k-axes direction */
    K_AXES_DIGIT = 1,
    /** H3 digit in j-axes direction */
    J_AXES_DIGIT = 2,
    /** H3 digit in j == k direction */
    JK_AXES_DIGIT = J_AXES_DIGIT | K_AXES_DIGIT, /* 3 */
    /** H3 digit in i-axes direction */
    I_AXES_DIGIT = 4,
    /** H3 digit in i == k direction */
    IK_AXES_DIGIT = I_AXES_DIGIT | K_AXES_DIGIT, /* 5 */
    /** H3 digit in i == j direction */
    IJ_AXES_DIGIT = I_AXES_DIGIT | J_AXES_DIGIT, /* 6 */
    /** H3 digit in the invalid direction */
    INVALID_DIGIT = 7,
    /** Valid digits will be less than this value. Same value as INVALID_DIGIT.
     */
    NUM_DIGITS = INVALID_DIGIT,
    /** Child digit which is skipped for pentagons */
    PENTAGON_SKIPPED_DIGIT = K_AXES_DIGIT /* 1 */
} Direction;

/** @brief Vertex number to hexagon direction relationships (same face).
 */
static const Direction vertexNumToDirectionHex[NUM_HEX_VERTS] = {
    IJ_AXES_DIGIT, J_AXES_DIGIT,  JK_AXES_DIGIT,
    K_AXES_DIGIT,  IK_AXES_DIGIT, I_AXES_DIGIT};

/** @brief Vertex number to pentagon direction relationships (same face).
 */
static const Direction vertexNumToDirectionPent[NUM_PENT_VERTS] = {
    IJ_AXES_DIGIT, J_AXES_DIGIT, JK_AXES_DIGIT, IK_AXES_DIGIT, I_AXES_DIGIT};

I believe that should be the order of edge output as well.

@SkybuckFlying
Copy link
Contributor Author

SkybuckFlying commented Sep 19, 2022

OK thanks ! I think this will be usefull in two things:

  1. Connecting the centers together in a meaningfull way, basically following the IJK axis and such.
    and perhaps
  2. Visualizing the connections between the centers of hexagons, by construction a triangle between three hexagon centers so that opengl can do automatic backface culling of triangles which are facing away from camera.

Maybe a new technique can be created where simply "lines/edges" between two points can be backface culled away by pretending they were triangles and determining their clock winding order. Though then the CPU has to do this determination instead of OpenGL, but probably does not cost that much CPU.

Could be an adventage to do it per line, it still needs information about wielding order.

However I also came up with idea of using normal to detect if it points towards camera or not... theoretically I think this should work... but calculating a correct normal also needs some kind of winding order...

So there seem to be two backface culling techniques: one based on winding order of 2D triangles, one based on 3D winding order of 3D triangles using normals... hmmm...

However the 3D face normal method might not work well for perspective and wireframes, something I think I noticed as well.

This thread seems to be about this as well, not sure, it's a bit vague matter:

https://stackoverflow.com/questions/67175750/how-to-use-face-normal-for-back-face-culling-in-perspective-projection-scenes

"Moreover, it is possible to have a triangle with normal pointed away from view direction and yet faced to the camera."

Maybe opposite is possible to... towards view direction, but away from camera...

It might still be possible to use normals.

This document seems to describe the fov which happens for perspective and also a technique which it calls normal masks:

"
Fast Backface Culling Using Normal Masks
Hansong Zhang∗ Kenneth E. Hoff III∗
"
Link:
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwiH0-rzx6H6AhVW_7sIHe6mDXIQFnoECAMQAQ&url=https%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.185.3782%26rep%3Drep1%26type%3Dpdf&usg=AOvVaw1xh04t6051j3PQihnnLYoS

Not sure how usefull or accurate this is, just exploring different implementation options for back face culling to make it better to look at, possibly easier to implement and maybe it allows more shapes, like points, lines to be backface culled and hopefully also somewhat better performance ! ;)

For now this document seems to be about polygons only... "proper" backface culling for points or line segments would be nice too.

@SkybuckFlying
Copy link
Contributor Author

SkybuckFlying commented Mar 10, 2023

(current picture is using directed edges api... to get the neighbour cells/indexes/centers, etc and the colored lines are connecting them, but only half-way per cell... (line till the edge of the cell border) so that each cell is treated individually.)

It seems to edges are not really consistent... or at least it's hard to see or hard to tell, what kind of consistency there is.

There might be some consistency, but for now it's oblivious to me... I am not numbering the cells, and not using any ijk things...

Just examining the borders, edges, vertex indexes, etc.

Maybe if using ijk or cell numbers, maybe some pattern might be visible... see picture
Uber H3 Edges order inconsistent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants