Given 4 vertices representing a quadrilateral, divide it into N parts











up vote
1
down vote

favorite












I am attempting to, given two dimensions (width and height) which represent a quadrilateral, partition that quad in to N parts where each part is as proportionally similar to the other as possible.



For example, imagine a sheet of paper. It consists of 4 points A, B, C, D. Now consider that the sheet of paper has the dimensions 800 x 800 and the points:



A: {0, 0}
B: {0, 800}
C: {800, 800}
D: {800, 0}


Plotting that will give you 4 points, or 3 lines with a line plot. Add an additional point E: {0, 0} to close the cell.



To my surprise, I've managed to do this programatically, for N number of cells.



How can I improve this code to make it more readable, pythonic, and as performant as possible?



from math import floor, ceil
import matplotlib.pyplot as plt


class QuadPartitioner:

@staticmethod
def get_factors(number):
'''
Takes a number and returns a list of factors
:param number: The number for which to find the factors
:return: a list of factors for the given number
'''
facts =
for i in range(1, number + 1):
if number % i == 0:
facts.append(i)
return facts

@staticmethod
def get_partitions(N, quad_width, quad_height):

'''
Given a width and height, partition the area into N parts
:param N: The number of partitions to generate
:param quad_width: The width of the quadrilateral
:param quad_height: The height of the quadrilateral
:return: a list of a list of cells where each cell is defined as a list of 5 verticies
'''

# We reverse only because my brain feels more comfortable looking at a grid in this way
factors = list(reversed(QuadPartitioner.get_factors(N)))

# We need to find the middle of the factors so that we get cells
# with as close to equal width and heights as possible

factor_count = len(factors)

# If even number of factors, we can partition both horizontally and vertically.
# If not even, we can only partition on the X axis
if factor_count % 2 == 0:
split = int(factor_count/2)
factors = factors[split-1:split+1]
else:
factors =
split = ceil(factor_count/2)
factors.append(split)
factors.append(split)

# The width and height of an individual cell
cell_width = quad_width / factors[0]
cell_height = quad_height / factors[1]

number_of_cells_in_a_row = factors[0]
rows = factors[1]
row_of_cells =

# We build just a single row of cells
# then for each additional row, we just duplicate this row and offset the cells
for n in range(0, number_of_cells_in_a_row):
cell_points =

for i in range(0, 5):

cell_y = 0
cell_x = n * cell_width

if i == 2 or i == 3:
cell_x = n * cell_width + cell_width

if i == 1 or i == 2:
cell_y = cell_height

cell_points.append((cell_x, cell_y))

row_of_cells.append(cell_points)

rows_of_cells = [row_of_cells]

# With that 1 row of cells constructed, we can simply duplicate it and offset it
# by the height of a cell multiplied by the row number
for index in range(1, rows):
new_row_of_cells = [[ (point[0],point[1]+cell_height*index) for point in square] for square in row_of_cells]
rows_of_cells.append(new_row_of_cells)

return rows_of_cells


if __name__ == "__main__":

QP = QuadPartitioner()
partitions = QP.get_partitions(56, 1980,1080)

for row_of_cells in partitions:
for cell in row_of_cells:
x, y = zip(*cell)
plt.plot(x, y, marker='o')

plt.show()


Output:



enter image description here










share|improve this question




























    up vote
    1
    down vote

    favorite












    I am attempting to, given two dimensions (width and height) which represent a quadrilateral, partition that quad in to N parts where each part is as proportionally similar to the other as possible.



    For example, imagine a sheet of paper. It consists of 4 points A, B, C, D. Now consider that the sheet of paper has the dimensions 800 x 800 and the points:



    A: {0, 0}
    B: {0, 800}
    C: {800, 800}
    D: {800, 0}


    Plotting that will give you 4 points, or 3 lines with a line plot. Add an additional point E: {0, 0} to close the cell.



    To my surprise, I've managed to do this programatically, for N number of cells.



    How can I improve this code to make it more readable, pythonic, and as performant as possible?



    from math import floor, ceil
    import matplotlib.pyplot as plt


    class QuadPartitioner:

    @staticmethod
    def get_factors(number):
    '''
    Takes a number and returns a list of factors
    :param number: The number for which to find the factors
    :return: a list of factors for the given number
    '''
    facts =
    for i in range(1, number + 1):
    if number % i == 0:
    facts.append(i)
    return facts

    @staticmethod
    def get_partitions(N, quad_width, quad_height):

    '''
    Given a width and height, partition the area into N parts
    :param N: The number of partitions to generate
    :param quad_width: The width of the quadrilateral
    :param quad_height: The height of the quadrilateral
    :return: a list of a list of cells where each cell is defined as a list of 5 verticies
    '''

    # We reverse only because my brain feels more comfortable looking at a grid in this way
    factors = list(reversed(QuadPartitioner.get_factors(N)))

    # We need to find the middle of the factors so that we get cells
    # with as close to equal width and heights as possible

    factor_count = len(factors)

    # If even number of factors, we can partition both horizontally and vertically.
    # If not even, we can only partition on the X axis
    if factor_count % 2 == 0:
    split = int(factor_count/2)
    factors = factors[split-1:split+1]
    else:
    factors =
    split = ceil(factor_count/2)
    factors.append(split)
    factors.append(split)

    # The width and height of an individual cell
    cell_width = quad_width / factors[0]
    cell_height = quad_height / factors[1]

    number_of_cells_in_a_row = factors[0]
    rows = factors[1]
    row_of_cells =

    # We build just a single row of cells
    # then for each additional row, we just duplicate this row and offset the cells
    for n in range(0, number_of_cells_in_a_row):
    cell_points =

    for i in range(0, 5):

    cell_y = 0
    cell_x = n * cell_width

    if i == 2 or i == 3:
    cell_x = n * cell_width + cell_width

    if i == 1 or i == 2:
    cell_y = cell_height

    cell_points.append((cell_x, cell_y))

    row_of_cells.append(cell_points)

    rows_of_cells = [row_of_cells]

    # With that 1 row of cells constructed, we can simply duplicate it and offset it
    # by the height of a cell multiplied by the row number
    for index in range(1, rows):
    new_row_of_cells = [[ (point[0],point[1]+cell_height*index) for point in square] for square in row_of_cells]
    rows_of_cells.append(new_row_of_cells)

    return rows_of_cells


    if __name__ == "__main__":

    QP = QuadPartitioner()
    partitions = QP.get_partitions(56, 1980,1080)

    for row_of_cells in partitions:
    for cell in row_of_cells:
    x, y = zip(*cell)
    plt.plot(x, y, marker='o')

    plt.show()


    Output:



    enter image description here










    share|improve this question


























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am attempting to, given two dimensions (width and height) which represent a quadrilateral, partition that quad in to N parts where each part is as proportionally similar to the other as possible.



      For example, imagine a sheet of paper. It consists of 4 points A, B, C, D. Now consider that the sheet of paper has the dimensions 800 x 800 and the points:



      A: {0, 0}
      B: {0, 800}
      C: {800, 800}
      D: {800, 0}


      Plotting that will give you 4 points, or 3 lines with a line plot. Add an additional point E: {0, 0} to close the cell.



      To my surprise, I've managed to do this programatically, for N number of cells.



      How can I improve this code to make it more readable, pythonic, and as performant as possible?



      from math import floor, ceil
      import matplotlib.pyplot as plt


      class QuadPartitioner:

      @staticmethod
      def get_factors(number):
      '''
      Takes a number and returns a list of factors
      :param number: The number for which to find the factors
      :return: a list of factors for the given number
      '''
      facts =
      for i in range(1, number + 1):
      if number % i == 0:
      facts.append(i)
      return facts

      @staticmethod
      def get_partitions(N, quad_width, quad_height):

      '''
      Given a width and height, partition the area into N parts
      :param N: The number of partitions to generate
      :param quad_width: The width of the quadrilateral
      :param quad_height: The height of the quadrilateral
      :return: a list of a list of cells where each cell is defined as a list of 5 verticies
      '''

      # We reverse only because my brain feels more comfortable looking at a grid in this way
      factors = list(reversed(QuadPartitioner.get_factors(N)))

      # We need to find the middle of the factors so that we get cells
      # with as close to equal width and heights as possible

      factor_count = len(factors)

      # If even number of factors, we can partition both horizontally and vertically.
      # If not even, we can only partition on the X axis
      if factor_count % 2 == 0:
      split = int(factor_count/2)
      factors = factors[split-1:split+1]
      else:
      factors =
      split = ceil(factor_count/2)
      factors.append(split)
      factors.append(split)

      # The width and height of an individual cell
      cell_width = quad_width / factors[0]
      cell_height = quad_height / factors[1]

      number_of_cells_in_a_row = factors[0]
      rows = factors[1]
      row_of_cells =

      # We build just a single row of cells
      # then for each additional row, we just duplicate this row and offset the cells
      for n in range(0, number_of_cells_in_a_row):
      cell_points =

      for i in range(0, 5):

      cell_y = 0
      cell_x = n * cell_width

      if i == 2 or i == 3:
      cell_x = n * cell_width + cell_width

      if i == 1 or i == 2:
      cell_y = cell_height

      cell_points.append((cell_x, cell_y))

      row_of_cells.append(cell_points)

      rows_of_cells = [row_of_cells]

      # With that 1 row of cells constructed, we can simply duplicate it and offset it
      # by the height of a cell multiplied by the row number
      for index in range(1, rows):
      new_row_of_cells = [[ (point[0],point[1]+cell_height*index) for point in square] for square in row_of_cells]
      rows_of_cells.append(new_row_of_cells)

      return rows_of_cells


      if __name__ == "__main__":

      QP = QuadPartitioner()
      partitions = QP.get_partitions(56, 1980,1080)

      for row_of_cells in partitions:
      for cell in row_of_cells:
      x, y = zip(*cell)
      plt.plot(x, y, marker='o')

      plt.show()


      Output:



      enter image description here










      share|improve this question















      I am attempting to, given two dimensions (width and height) which represent a quadrilateral, partition that quad in to N parts where each part is as proportionally similar to the other as possible.



      For example, imagine a sheet of paper. It consists of 4 points A, B, C, D. Now consider that the sheet of paper has the dimensions 800 x 800 and the points:



      A: {0, 0}
      B: {0, 800}
      C: {800, 800}
      D: {800, 0}


      Plotting that will give you 4 points, or 3 lines with a line plot. Add an additional point E: {0, 0} to close the cell.



      To my surprise, I've managed to do this programatically, for N number of cells.



      How can I improve this code to make it more readable, pythonic, and as performant as possible?



      from math import floor, ceil
      import matplotlib.pyplot as plt


      class QuadPartitioner:

      @staticmethod
      def get_factors(number):
      '''
      Takes a number and returns a list of factors
      :param number: The number for which to find the factors
      :return: a list of factors for the given number
      '''
      facts =
      for i in range(1, number + 1):
      if number % i == 0:
      facts.append(i)
      return facts

      @staticmethod
      def get_partitions(N, quad_width, quad_height):

      '''
      Given a width and height, partition the area into N parts
      :param N: The number of partitions to generate
      :param quad_width: The width of the quadrilateral
      :param quad_height: The height of the quadrilateral
      :return: a list of a list of cells where each cell is defined as a list of 5 verticies
      '''

      # We reverse only because my brain feels more comfortable looking at a grid in this way
      factors = list(reversed(QuadPartitioner.get_factors(N)))

      # We need to find the middle of the factors so that we get cells
      # with as close to equal width and heights as possible

      factor_count = len(factors)

      # If even number of factors, we can partition both horizontally and vertically.
      # If not even, we can only partition on the X axis
      if factor_count % 2 == 0:
      split = int(factor_count/2)
      factors = factors[split-1:split+1]
      else:
      factors =
      split = ceil(factor_count/2)
      factors.append(split)
      factors.append(split)

      # The width and height of an individual cell
      cell_width = quad_width / factors[0]
      cell_height = quad_height / factors[1]

      number_of_cells_in_a_row = factors[0]
      rows = factors[1]
      row_of_cells =

      # We build just a single row of cells
      # then for each additional row, we just duplicate this row and offset the cells
      for n in range(0, number_of_cells_in_a_row):
      cell_points =

      for i in range(0, 5):

      cell_y = 0
      cell_x = n * cell_width

      if i == 2 or i == 3:
      cell_x = n * cell_width + cell_width

      if i == 1 or i == 2:
      cell_y = cell_height

      cell_points.append((cell_x, cell_y))

      row_of_cells.append(cell_points)

      rows_of_cells = [row_of_cells]

      # With that 1 row of cells constructed, we can simply duplicate it and offset it
      # by the height of a cell multiplied by the row number
      for index in range(1, rows):
      new_row_of_cells = [[ (point[0],point[1]+cell_height*index) for point in square] for square in row_of_cells]
      rows_of_cells.append(new_row_of_cells)

      return rows_of_cells


      if __name__ == "__main__":

      QP = QuadPartitioner()
      partitions = QP.get_partitions(56, 1980,1080)

      for row_of_cells in partitions:
      for cell in row_of_cells:
      x, y = zip(*cell)
      plt.plot(x, y, marker='o')

      plt.show()


      Output:



      enter image description here







      python python-3.x






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 1 hour ago









      Jamal

      30.2k11115226




      30.2k11115226










      asked 1 hour ago









      pookie

      12314




      12314



























          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209745%2fgiven-4-vertices-representing-a-quadrilateral-divide-it-into-n-parts%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209745%2fgiven-4-vertices-representing-a-quadrilateral-divide-it-into-n-parts%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Quarter-circle Tiles

          build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

          Mont Emei