Hello
How can I define the following GHPython code to solve following problem?
The cylinder is divided in 3 sectors. The height of the cylinder h should be here constant.
Therefore, I would like change the height of any sector how I want and the other two sectors will change automatically, but the sum of the height of the 3 sectors should not be more than the height h.
Here is a screen shot of the cylinder divided in 3 sectors.
You start at a base point, set a maximum height, a desired distance between segments and a segment count. The script evaluates the minimum allowed distance between segments by dividing the maximum height by the desired segment count.
If the calculated minimum distance is exceeded by the desired distance between segments, the minimum distance becomes the distance between segments.
The script outputs points that can be used as center points for the section circles. However, it could be easily extended to do everything!
import Rhino.Geometry as rg
# Calculate the minimum allowed distance between the segments
min_dist = MaxHeight / (Count)
dist = Distance
# Set the distance to the minimum distance if it exceeds the maximum height
if dist > min_dist:
dist = min_dist
# Construct the points
pts = []
for i in xrange(Count+1):
pt = rg.Point3d(BasePoint.X, BasePoint.Y, i * dist)
pts.append(pt)
# Outputs
a = pts
OK, so in your scenario, what would happen if the distance of the first section is bigger than the maximum height? Or if both, the first and second distance, are bigger than the maximum one? Or if both added together are equal to or bigger than the maximum height?
OK, so in your scenario, what would happen if the distance of the first section is bigger than the maximum height? Or if both, the first and second distances, are bigger than the maximum one? Or if both added together are equal to or bigger than the maximum height?
Well, the distance of any section should not be smaller than zero or bigger than 15 cm. The sum of 3 sections should not be more than 15 cm. One section can be zero and others can be 5 cm and 10 cm, for exemple. But the maximum height must be the same defined value.
Or if both added together are equal to or bigger than the maximum height?
They should be equal to the maximum height.
It should now do what you described above. If one or both distance values exceed the distance between the end points, the input distances get remapped to fit within the limits, and only two segments are produced.
"""Divides the distance between a start and end point into a desired number of
segments. The distance between the first two segments corresponds to the
desired distance values, whereas the remaining distance is divided equally.
If one or both desired distances exceed the distance between both points,
both distances get remapped to fit the limits.
Inputs:
StartPoint: Start point
EndPoint: End point
Count: Number of segments
Dist1: Distance of the first segment
Dist2: Distance of the second segment
Output:
Points: Division points"""
ghenv.Component.Name = "PythonicCustomDivide"
ghenv.Component.NickName = "CustomDivide"
__author__ = "p1r4t3b0y"
__email__ = "p1r4t3b0y@gmail.com"
__version__ = "1.0"
import Rhino.Geometry as rg
def fit(value, source_min, source_max, target_min, target_max):
"""Fits a value into new numeric domain.
Args:
value (int, float): A value to remap.
source_min: A start value of the source domain.
source_max: An end value of the source domain.
target_min: A start value of the target domain.
target_max: An end value of the target domain.
Returns:
The remapped value.
"""
source_range = source_max - source_min
if source_range == 0:
new_value = target_min
else:
target_range = target_max - target_min
new_value = (((value - source_min) * target_range) / \
source_range) + target_min
return new_value
# Get the directional vector
dir = EndPoint - StartPoint
# Get the maximum distance between the start and end point
max_dist = dir.Length
# Calculate the rest length
rest_len = max_dist - (Dist1 + Dist2)
# Unitize the directional vector to length 1
dir.Unitize()
div_pts = [] # divison points
# Get the division points
if rest_len >= 0: # rest length supports at least the first two divisions
# Calculate the division length beyond the second divison
div_len = rest_len / (Count - 2)
init_dists = [Dist1, Dist2] # initial distances
trav_dist = 0.0 # already travelled distance
for i in xrange(Count+1):
if i == 0: # the start point is the first division point
div_pts.append(StartPoint)
else: # other division points
# Process the desired first and second division points first
if len(init_dists) > 0:
trav_dist += init_dists[0]
next_pt = StartPoint + dir * trav_dist
div_pts.append(next_pt)
del init_dists[0]
# Process the remaining divisions
else:
# The following two lines are optional!
if rest_len == 0.0: # no rest length to divide
break # don't produce points
trav_dist += div_len
next_pt = StartPoint + dir * trav_dist
div_pts.append(next_pt)
else: # rest length does not supports even the first two divisions
# Remap the desired distances to fit between 0.0 and the maximum distance
d1 = fit(Dist1, 0.0, max([Dist1, Dist2]), 0.0, max_dist)
d2 = fit(Dist2, 0.0, max([Dist1, Dist2]), 0.0, max_dist)
min_d, max_d = sorted([d1, d2])
init_dists = [min_d, max_d - min_d] # initial distances
trav_dist = 0.0 # already travelled distance
print init_dists
for i in xrange(3):
if i == 0: # the start point is the first division point
div_pts.append(StartPoint)
else: # other division points
# Process only the remapped first and second division points
if len(init_dists) > 0:
trav_dist += init_dists[0]
next_pt = StartPoint + dir * trav_dist
div_pts.append(next_pt)
del init_dists[0]
# Outputs
Points = div_pts