Ejemplo n.º 1
0
def division_line(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the bounding box of
    the division line as specified in Rule 1, Section 5, Article 1 of the NCAA
    rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature
    
    Returns
    -------
    division_line: A pandas dataframe of the interior boundaries of the court
    """
    # The line's center should be 47' from the interior side of the baselines,
    # and must be 2" thick
    division_line = create.rectangle(x_min=-1 / 12,
                                     x_max=0,
                                     y_min=-25,
                                     y_max=25)

    # Reflect the x coordinates over the y axis
    if full_surf:
        division_line = division_line.append(
            transform.reflect(division_line, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        division_line = transform.rotate(division_line, rotation_dir)

    return division_line
Ejemplo n.º 2
0
def nets(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the rings as specified
    in Rule 1, Section 14, Article 2 of the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature

    Returns
    -------
    nets: a pandas dataframe of the nets
    """
    # The ring's center is 15" from the backboard, and 63" from the baseline,
    # which means it is centered at (+/-41.75, 0). The ring has an interior
    # diameter of 18", which is where the net is visible from above
    net = create.circle(center=(-41.75, 0), d=1.5)

    # Reflect the x coordinates over the y axis
    if full_surf:
        net = net.append(transform.reflect(net, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        net = transform.rotate(net, rotation_dir)

    return net
Ejemplo n.º 3
0
def backboards(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the backboard as
    specified in Rule 1, Section 10, Article 2 of the NCAA rule book

    Returns
    -------
    backboard: a pandas dataframe of the backboard
    """
    # Per the rule book, the backboard must by 6' wide. The height of the
    # backboard is irrelevant in this graphic, as this is a bird's eye view
    # over the court
    backboard = create.rectangle(x_min=-43 - (4 / 12),
                                 x_max=-43,
                                 y_min=-3,
                                 y_max=3)

    # Reflect the x coordinates over the y axis
    if full_surf:
        backboard = backboard.append(transform.reflect(backboard, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        backboard = transform.rotate(backboard, rotation_dir)

    return backboard
Ejemplo n.º 4
0
def bench_areas(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the team bench areas
    as specified on the court diagram in the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature
    
    Returns
    -------
    bench_areas: a pandas dataframe of the team bench areas
    """
    # The bench area is 28 feet from the interior of the endline, is 2" wide,
    # and extends 3' on each side of the sideline
    bench_area = create.rectangle(x_min=-19 - (2 / 12),
                                  x_max=-19,
                                  y_min=22,
                                  y_max=28)

    # Reflect the x coordinates over the y axis
    if full_surf:
        bench_area = bench_area.append(
            transform.reflect(bench_area, over_y=True))
    # Rotate the coordinates if necessary
    if rotate:
        bench_area = transform.rotate(bench_area, rotation_dir)

    return bench_area
Ejemplo n.º 5
0
def painted_areas(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the bounding box of the
    free throw lane as specified in Rule 1, Section 6, Articles 1, 2, 3, and 4
    of the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature
    
    Returns
    -------
    painted_areas: a pandas dataframe of the painted areas
    """
    # The interior of the free throw lane is known as the painted area, and
    # can be a different color than the markings and court. These coordinates
    # can be used to color them on the plot
    painted_area = create.rectangle(x_min=-47,
                                    xmax=-28 - (2 / 12),
                                    y_min=-6 + (2 / 12),
                                    y_max=6 - (2 / 12))

    # Reflect the x coordinates over the y axis
    if full_surf:
        painted_area = painted_area.append(
            transform.reflect(painted_area, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        painted_area = transform.rotate(painted_area, rotation_dir)

    return painted_area
Ejemplo n.º 6
0
def coaching_boxes(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the bounding box of the
    coaching boxes as specified in Rule 1, Section 9, Articles 1 and 2 of the
    NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature
    
    Returns
    -------
    coaching_boxes: a pandas dataframe of the sidelines
    """
    # The coaching boxes are 38' from the interior of the baseline on each
    # side of the court, and extend 2' out of bounds from the exterior of the
    # sideline
    coaching_box = create.rectangle(x_min=-9 - (2 / 12),
                                    x_max=-9,
                                    y_min=25,
                                    y_max=27)

    # Reflect the x coordinates over the y axis
    if full_surf:
        coaching_box = coaching_box.append(
            transform.reflect(coaching_box, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        coaching_box = transform.rotate(coaching_box, rotation_dir)

    return coaching_box
Ejemplo n.º 7
0
def restricted_area_arcs(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the restricted-area
    arcs as specified in Rule 1, Section 8 of the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature

    Returns
    -------
    restricted_area_arcs: a pandas dataframe of the restricted-area arcs
    """
    # The restricted area arc is an arc of radius 4' from the center of the
    # basket, and extending in a straight line to the front face of the
    # backboard, and having thickness of 2"
    restricted_area_arc = pd.DataFrame({
        'x': [-43],
        'y': [-4 - (2 / 12)]
    }).append(
        create.circle(center=(-41.75, 0),
                      d=8 + (4 / 12),
                      start=-1 / 2,
                      end=1 / 2)).append(
                          pd.DataFrame({
                              'x': [-43, -43],
                              'y': [4 + (2 / 12), 4]
                          })).append(
                              create.circle(center=(-41.75, 0),
                                            d=8,
                                            start=1 / 2,
                                            end=-1 / 2)).append(
                                                pd.DataFrame({
                                                    'x': [-43, -43],
                                                    'y': [-4, -4 - (2 / 12)]
                                                }))

    # Reflect the x coordinates over the y axis
    if full_surf:
        restricted_area_arc = restricted_area_arc.append(
            transform.reflect(restricted_area_arc, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        restricted_area_arc = transform.rotate(rotation_dir,
                                               restricted_area_arc)

    return restricted_area_arc
Ejemplo n.º 8
0
def goals(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the goals as specified
    in Rule 1, Sections 14 and 15 of the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature
    
    Returns
    -------
    goals: a pandas dataframe of the goals
    """
    # Get the starting angle of the ring. The connector has a width of 5", so
    # 2.5" are on either side. The ring has a radius of 9", so the arcsine of
    # these measurements should give the angle at which point they connect
    start_angle = np.pi - math.asin(2.5 / 9)

    # The ending angle of the ring would be the negative of the starting angle
    end_angle = -start_angle

    # Define the coordinates for the goal
    goal = pd.DataFrame({
        'x': [-43, -41.75 - ((9 / 12) * math.cos(start_angle))],
        'y': [2.5 / 12, 2.5 / 12]
    }).append(
        create.circle(
            center=(-41.75, 0),
            start=start_angle,
            end=end_angle,
            d=1.5 + (4 / 12))).append(
                pd.DataFrame({
                    'x':
                    [-41.75 - ((9 / 12) * math.cos(start_angle)), -43, -43],
                    'y': [-2.5 / 12, -2.5 / 12, 2.5 / 12]
                }))

    # Reflect the x coordinates over the y axis
    if full_surf:
        goal = goal.append(transform.reflect(goal, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        goal = transform.rotate(goal, rotation_dir)

    return goal
Ejemplo n.º 9
0
def free_throw_circles(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the free-throw circles
    as specified on the court diagram in the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature

    Returns
    -------
    free_throw_circles: a pandas dataframe of the free-throw circle
    """
    # The free-throw circle is 6' in diameter from the center of the free-throw
    # line (exterior)
    free_throw_circle = create.circle(
        center=(-28, 0), start=-1 / 2, end=1 / 2,
        d=12).append(pd.DataFrame({
            'x': [-28],
            'y': [6]
        })).append(
            create.circle(center=(-28, 0),
                          start=1 / 2,
                          end=-1 / 2,
                          d=12 - (4 / 12))).append(
                              pd.DataFrame({
                                  'x': [-28],
                                  'y': [-6]
                              }))

    # Reflect the x coordinates over the y axis
    if full_surf:
        free_throw_circle = free_throw_circle.append(
            transform.reflect(free_throw_circle, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        free_throw_circle = transform.rotate(free_throw_circle, rotation_dir)

    return free_throw_circle
Ejemplo n.º 10
0
def w_three_pt_lines(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the three-point line
    as specified in Rule 1, Section 7 of the NCAA rule book. These points are
    the women's three-point line, and also where the men's three-point line was
    prior to the 2019-2020 season. While this line only pertains to women's
    basketball, universities typically only have one court for both teams, so
    this marking appears on the men's floor as well

    Returns
    -------
    w_three_pt_lines: a pandas dataframe of the three-point line
    """
    # This can be computed similarly to how the men's line was computed
    w_three_pt_line = pd.DataFrame({
        'x': [-47],
        'y': [-20.75]
    }).append(
        create.circle(
            center=(-41.75, 0), d=41.5, start=-1 / 2, end=1 / 2)).append(
                pd.DataFrame({
                    'x': [-47, -47],
                    'y': [20.75, 20.75 - (2 / 12)]
                })).append(
                    create.circle(center=(-41.75, 0),
                                  d=41.5 - (4 / 12),
                                  start=1 / 2,
                                  end=-1 / 2)).append(
                                      pd.DataFrame({
                                          'x': [-47, -47],
                                          'y': [-20.75 + (2 / 12), -20.75]
                                      }))

    # Reflect the x coordinates over the y axis
    if full_surf:
        w_three_pt_line = w_three_pt_line.append(
            transform.reflect(w_three_pt_line, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        w_three_pt_line = transform.rotate(w_three_pt_line, rotation_dir)

    return w_three_pt_line
Ejemplo n.º 11
0
def court_border(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the bounding box of the
    court border as specified in the court diagram of the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature

    Returns
    -------
    court_border: a pandas dataframe of the court border
    """
    # Courts have borders around the outside of the court that are different
    # in color than the end lines and sidelines. They are usually about 5' on
    # the sidelines and 8' on the end lines
    court_border = pd.DataFrame({
        'x': [
            0, -47 - (2 / 12), -47 - (2 / 12), 0, 0, -55 - (4 / 12),
            -55 - (4 / 12), 0, 0
        ],
        'y': [
            -25 - (2 / 12), -25 - (2 / 12), 25 + (2 / 12), 25 + (2 / 12),
            30 + (2 / 12), 30 + (2 / 12), -30 - (2 / 12), -30 - (2 / 12),
            -25 - (2 / 12)
        ]
    })

    # Reflect the x coordinates over the y axis
    if full_surf:
        court_border = court_border.append(
            transform.reflect(court_border, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        court_border = transform.rotate(court_border, rotation_dir)

    return court_border
Ejemplo n.º 12
0
def center_circle(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the center circle as
    specified in Rule 1, Section 4, Article 1 of the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature

    Returns
    -------
    center_circle: A pandas dataframe containing the points that comprise the
        center circle of the court
    """
    # Draw the right outer semicircle, then move in 2" per the NCAA's required
    # line thickness, and draw inner semicircle. Doing it this way alleviates
    # future fill issues.
    center_circle = create.circle(d=12, start=1 / 2, end=3 / 2).append(
        pd.DataFrame({
            'x': [0],
            'y': [6 - (2 / 12)]
        })).append(create.circle(d=12 - (4 / 12), start=3 / 2,
                                 end=1 / 2)).append(
                                     pd.DataFrame({
                                         'x': [0],
                                         'y': [-6]
                                     }))

    # Reflect the x coordinates over the y axis
    if full_surf:
        center_circle = center_circle.append(
            transform.reflect(center_circle, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        center_circle = transform.rotate(center_circle, rotation_dir)

    return center_circle
Ejemplo n.º 13
0
def lower_defensive_box_ticks(full_surf=True,
                              rotate=False,
                              rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the bounding box of the
    lower defensive box tick marks as specified in Rule 1, Section 3, Article 7
    of the NCAA rule book (women's only). While it only pertains to women's
    basketball, universities typically only have one court for both teams, so
    this marking appears on the men's floor as well
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature
    
    Returns
    -------
    endline_sideline: a pandas dataframe of the end lines and side lines
    """
    # The defensive box is marked by two 2"-thick tick marks, each being 3'
    # from the edge of the lane and extending 12" into the court
    lower_defensive_box_tick = create.rectangle(x_min=-47,
                                                x_max=-46,
                                                y_min=-9 - (2 / 12),
                                                y_max=-9)

    # Reflect the x coordinates over the y axis
    if full_surf:
        lower_defensive_box_tick = lower_defensive_box_tick.append(
            transform.reflect(lower_defensive_box_tick, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        lower_defensive_box_tick = transform.rotate(lower_defensive_box_tick,
                                                    rotation_dir)

    return lower_defensive_box_tick
Ejemplo n.º 14
0
def endlines_sidelines(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the bounding box of the
    end lines and sidelines as specified in Rule 1, Section 3, Article 2 of
    the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature

    Returns
    -------
    endline_sideline: a pandas dataframe of the end lines and side lines
    """
    # The endline and sideline form the boundary of the court
    endline_sideline = pd.DataFrame({
        'x': [0, -47, -47, 0, 0, -47 - (2 / 12), -47 - (2 / 12), 0, 0],
        'y': [
            -25, -25, 25, 25, 25 + (2 / 12), 25 + (2 / 12), -25 - (2 / 12),
            -25 - (2 / 12), -25
        ]
    })

    # Reflect the x coordinates over the y axis
    if full_surf:
        endline_sideline = endline_sideline.append(
            transform.reflect(endline_sideline, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        endline_sideline = transform.rotate(endline_sideline, rotation_dir)

    return endline_sideline
Ejemplo n.º 15
0
def m_three_pt_lines(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the three-point line
    as specified in Rule 1, Section 7 of the NCAA rule book. These points are
    the men's three-point line after being moved back prior to the 2019-2020
    season
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature
    
    Returns
    -------
    m_three_pt_lines: a pandas dataframe of the three-point line
    """
    # First, a bit of math is needed to determine the starting and ending
    # angles of the three-point arc, relative to 0 radians. Since in the end,
    # the angle is what matters, the units of measure do not. Inches are easier
    # to use for this calculation. The angle begins 9' 10 3/8" from the
    # interior edge of the endline
    start_x = (9 * 12) + 10 + (3 / 8)

    # However, the rule book describes the arc as having a radius of 22' 1.75"
    # from the center of the basket. The basket's center is 63" away from the
    # interior of the endline, so this must be subtracted from our starting x
    # position to get the starting x position *relative to the center of the
    # basket*
    start_x -= 63
    radius_outer = (22 * 12) + 1.75

    # From here, the calculation is relatively straightforward. To determine
    # the angle, the inverse cosine is needed. It will be multiplied by pi
    # so that it can be passed to the create_circle() function
    start_angle_outer = math.acos(start_x / radius_outer) / np.pi
    end_angle_outer = -start_angle_outer

    # The same method can be used for the inner angles, however, since the
    # inner radius will be traced from bottom to top, the angle must be
    # negative to start
    radius_inner = (22 * 12) + 1.75 - 2
    start_angle_inner = -math.acos(start_x / radius_inner) / np.pi
    end_angle_inner = -start_angle_inner

    # According to the rulebook, the three-point line is 21' 7 7/8" in the
    # corners
    m_three_pt_line = pd.DataFrame({
        'x': [-47],
        'y': [21 + ((7 + (7 / 8)) / 12)]
    }).append(
        create.circle(
            center=(-41.75, 0),
            d=2 * (((22 * 12) + 1.75) / 12),
            start=start_angle_outer,
            end=end_angle_outer)).append(
                pd.DataFrame({
                    'x': [-47, -47, -47 + (((9 * 12) + 10 + (3 / 8)) / 12)],
                    'y': [
                        -21 - ((7 + (7 / 8)) / 12),
                        -21 - ((7 + (7 / 8)) / 12) + (2 / 12),
                        -21 - ((7 + (7 / 8)) / 12) + (2 / 12)
                    ]
                })).append(
                    create.circle(
                        center=(-41.75, 0),
                        d=2 * ((((22 * 12) + 1.75) / 12) - (2 / 12)),
                        start=start_angle_inner,
                        end=end_angle_inner)).append(
                            pd.DataFrame({
                                'x': [
                                    -47 + (((9 * 12) + 10 + (3 / 8)) / 12),
                                    -47, -47
                                ],
                                'y': [
                                    21 + ((7 + (7 / 8)) / 12) - (2 / 12),
                                    21 + ((7 + (7 / 8)) / 12) - (2 / 12),
                                    21 + ((7 + (7 / 8)) / 12)
                                ]
                            }))

    # Reflect the x coordinates over the y axis
    if full_surf:
        m_three_pt_line = m_three_pt_line.append(
            transform.reflect(m_three_pt_line, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        m_three_pt_line = transform.rotate(rotation_dir, m_three_pt_line)

    return m_three_pt_line
Ejemplo n.º 16
0
def free_throw_lanes(full_surf=True, rotate=False, rotation_dir='ccw'):
    """
    Generate the dataframe for the points that comprise the bounding box of the
    free throw lane as specified in Rule 1, Section 6, Articles 1, 2, 3, and 4
    of the NCAA rule book
    
    Parameters
    ----------
    full_surf: a bool indicating whether or not this feature is needed for a
        full-surface representation
    rotate: a bool indicating whether or not this feature needs to be rotated
    rotation_dir: a string indicating which direction to rotate the feature

    Returns
    -------
    free_throw_lanes: a pandas dataframe of the free throw lanes
    painted_areas: a pandas dataframe of the painted areas
    """
    # The free throw lane goes from the endline inwards a distance of 18' 10"
    # (interior) and 19' (exterior) with a width of 6'

    # The first set of blocks are 7' from the interior of the baseline, and
    # measure 1' in width

    # The second set of blocks are 3' from the first block, and
    # measure 2" in width

    # The third set of blocks are 3' from the second block, and
    # measure 2" in width

    # The fourth set of blocks are 3' from the third block, and
    # measure 2" in width
    free_throw_lane = pd.DataFrame({
        'x': [
            # Start
            -47,

            # First block lower
            -40,
            -40,
            -39,
            -39,

            # Second block lower
            -36,
            -36,
            -36 + (2 / 12),
            -36 + (2 / 12),

            # Third block lower
            -33 + (2 / 12),
            -33 + (2 / 12),
            -33 + (4 / 12),
            -33 + (4 / 12),

            # Fourth block lower
            -30 + (4 / 12),
            -30 + (4 / 12),
            -30 + (6 / 12),
            -30 + (6 / 12),

            # End
            -28,

            # Cross
            -28,

            # Fourth block upper
            -30 + (6 / 12),
            -30 + (6 / 12),
            -30 + (4 / 12),
            -30 + (4 / 12),

            # Third block upper
            -33 + (2 / 12),
            -33 + (2 / 12),
            -33 + (4 / 12),
            -33 + (4 / 12),

            # Second block upper
            -36,
            -36,
            -36 + (2 / 12),
            -36 + (2 / 12),

            # First block upper
            -40,
            -40,
            -39,
            -39,

            # End of exterior
            -47,

            # Interior
            -47,
            -28 - (2 / 12),
            -28 - (2 / 12),
            -47,
            -47,
            -47
        ],
        'y': [
            -6,

            # First block lower
            -6,
            -6 - (8 / 12),
            -6 - (8 / 12),
            -6,

            # Second block lower
            -6,
            -6 - (8 / 12),
            -6 - (8 / 12),
            -6,

            # Third block lower
            -6,
            -6 - (8 / 12),
            -6 - (8 / 12),
            -6,

            # Fourth block lower
            -6,
            -6 - (8 / 12),
            -6 - (8 / 12),
            -6,

            # End
            -6,

            # Cross
            6,

            # Fourth block upper
            6,
            6 + (8 / 12),
            6 + (8 / 12),
            6,

            # Third block upper
            6,
            6 + (8 / 12),
            6 + (8 / 12),
            6,

            # Second block upper
            6,
            6 + (8 / 12),
            6 + (8 / 12),
            6,

            # First block upper
            6,
            6 + (8 / 12),
            6 + (8 / 12),
            6,

            # End of exterior
            6,

            # Interior
            6 - (2 / 12),
            6 - (2 / 12),
            -6 + (2 / 12),
            -6 + (2 / 12),
            6,
            -6
        ]
    })

    # Reflect the x coordinates over the y axis
    if full_surf:
        free_throw_lane = free_throw_lane.append(
            transform.reflect(free_throw_lane, over_y=True))

    # Rotate the coordinates if necessary
    if rotate:
        free_throw_lane = transform.rotate(free_throw_lane, rotation_dir)

    return free_throw_lane