CC calculation: clip_line - arnthor89/pygame GitHub Wiki
CC calculation clip_line
Function
def clip_line(line, left, top, right, bottom, use_float=False):
'''Algorithm to calculate the clipped line.
We calculate the coordinates of the part of the line segment within the
bounding box (defined by left, top, right, bottom). The we write
the coordinates of the line segment into "line", much like the C-algorithm.
With `use_float` True, clip_line is usable for float-clipping.
Returns: true if the line segment cuts the bounding box (false otherwise)
'''
assert isinstance(line, list)
x1, y1, x2, y2 = line
dtype = float if use_float else int
while True:
# the coordinates are progressively modified with the codes,
# until they are either rejected or correspond to the final result.
code1 = encode(x1, y1, left, top, right, bottom)
code2 = encode(x2, y2, left, top, right, bottom)
if ACCEPT(code1, code2):
# write coordinates into "line" !
line[:] = x1, y1, x2, y2
return True
if REJECT(code1, code2):
return False
# We operate on the (x1, y1) point, and swap if it is inside the bbox:
if INSIDE(code1):
x1, x2 = x2, x1
y1, y2 = y2, y1
code1, code2 = code2, code1
if (x2 != x1):
m = (y2 - y1) / float(x2 - x1)
else:
m = 1.0
# Each case, if true, means that we are outside the border:
# calculate x1 and y1 to be the "first point" inside the bbox...
if code1 & LEFT_EDGE:
y1 += dtype((left - x1) * m)
x1 = left
elif code1 & RIGHT_EDGE:
y1 += dtype((right - x1) * m)
x1 = right
elif code1 & BOTTOM_EDGE:
if x2 != x1:
x1 += dtype((bottom - y1) / m)
y1 = bottom
elif code1 & TOP_EDGE:
if x2 != x1:
x1 += dtype((top - y1) / m)
y1 = top
Control flow graph
def clip_line(line, left, top, right, bottom, use_float=False,brancharray):
'''Algorithm to calculate the clipped line.
We calculate the coordinates of the part of the line segment within the
bounding box (defined by left, top, right, bottom). The we write
the coordinates of the line segment into "line", much like the C-algorithm.
With `use_float` True, clip_line is usable for float-clipping.
Returns: true if the line segment cuts the bounding box (false otherwise)
'''
#1
assert isinstance(line, list)
x1, y1, x2, y2 = line
dtype = #2 float if use_float else #3 int
#4
while True:
#5
# the coordinates are progressively modified with the codes,
# until they are either rejected or correspond to the final result.
code1 = encode(x1, y1, left, top, right, bottom)
code2 = encode(x2, y2, left, top, right, bottom)
if ACCEPT(code1, code2):
# write coordinates into "line" !
#6
line[:] = x1, y1, x2, y2
return True
#7
if REJECT(code1, code2):
#8
return False
#9
# We operate on the (x1, y1) point, and swap if it is inside the bbox:
if INSIDE(code1):
#10
x1, x2 = x2, x1
y1, y2 = y2, y1
code1, code2 = code2, code1
#11
if (x2 != x1):
#12
m = (y2 - y1) / float(x2 - x1)
else:
#13
m = 1.0
# Each case, if true, means that we are outside the border:
# calculate x1 and y1 to be the "first point" inside the bbox...
#14
if code1 & LEFT_EDGE:
#15
y1 += dtype((left - x1) * m)
x1 = left
elif code1 & RIGHT_EDGE:
#16
y1 += dtype((right - x1) * m)
x1 = right
elif code1 & BOTTOM_EDGE:
#17
if x2 != x1:
#18
x1 += dtype((bottom - y1) / m)
y1 = bottom
#19
elif code1 & TOP_EDGE:
#20
if x2 != x1:
#21
x1 += dtype((top - y1) / m)
y1 = top
#22
#23
https://i.imgur.com/qA9hlaf.png
Calculation
- Edges = 32
- Nodes = 23
- Connected components = 1
32 - 23 + 2*1 = 11