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:
python python-3.x
add a comment |
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:
python python-3.x
add a comment |
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:
python python-3.x
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:
python python-3.x
python python-3.x
edited 1 hour ago
Jamal♦
30.2k11115226
30.2k11115226
asked 1 hour ago
pookie
12314
12314
add a comment |
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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