HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Determining which octant has a specific point

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
determiningpointoctanthasspecificwhich

Problem

I am interested in octants in plane geometry, which basically involves dividing a plane into 8 equal parts according to a certain point.

Octants are particularly useful while implementing the Bresenham's algorithm.

Problem

Given two points A = (x1, y1) and B = (x2, y2), how to determine in which octant belongs B according to A?

Counting octants is performed as shown: starting from the upper right and iterating anticlockwise.

Naive implementation

def get_octant(pA, pB):
    AX = pA[0]
    AY = pA[1]
    BX = pB[0]
    BY = pB[1]

    if BX > AX:
        if BY > AY:
            if (BY - AY)  AY:
            if (BY - AY) < (AX - BX):
                octant = 3
            else:
                octant = 2
        else:
            if (AY - BY) < (AX - BX):
                octant = 4
            else:
                octant = 5

    return octant


Would it not possible to find a cleverer implementation?

Using the symmetry properties, I am convinced that it is possible to make a shorter and more readable code. Unfortunately, I do not find it myself, so does anyone have an idea, please?

Solution

I am convinced that it is possible to make a shorter and more readable code.

To implement the discrete analog of atan2((B.y - A.y), (B.x - A.x)):

x, y  = (B.x - A.x), (B.y - A.y)
octant = [([1, 2], [8, 7]), ([4, 3], [5, 6])][x < 0][y < 0][abs(x) < abs(y)]


It is shorter, I don't know about readability. It is easy to write tests that check all possible variants including the behavior on the boundaries.

Code Snippets

x, y  = (B.x - A.x), (B.y - A.y)
octant = [([1, 2], [8, 7]), ([4, 3], [5, 6])][x < 0][y < 0][abs(x) < abs(y)]

Context

StackExchange Code Review Q#95550, answer score: 6

Revisions (0)

No revisions yet.