You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.rst
+82-11Lines changed: 82 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -111,6 +111,17 @@ There are many things you may want to modify as you grow your own trees. Here ar
111
111
112
112
2. **Changing Leaf Geometry:**
113
113
114
+
The call production of the leaves happens in the ``grow_object(o)`` section:
115
+
116
+
.. code-block:: python
117
+
118
+
elif'Leaf'in o.name:
119
+
produce L(.1)
120
+
121
+
Here, .1 is just a hard-coded value that doesn't have much significance.
122
+
123
+
The actual generation of the leaf can be seen in the ``L(l)`` production section:
124
+
114
125
.. code-block:: python
115
126
116
127
L(l):
@@ -119,11 +130,23 @@ There are many things you may want to modify as you grow your own trees. Here ar
119
130
curves = make_leaf_guide()
120
131
curve1 = curves[0]
121
132
curve2 = curves[1]
122
-
123
133
produce _(.0025) F(l/10){[SetGuide(curve1, l) _(.001).nF(l, .01)][SetGuide(curve2, l)_(.001).nF(l, .01)]}
134
+
135
+
The parameter here serves as the length of the leaf. To edit the shape of the leaf, edits can be made in the ``make_leaf_guide()`` function. In the ``make_leaf_guide()`` function, a BezierCurve2D and its inverse are generated. These are returned to be used as guides for the ``SetGuide`` function provided by L-Py. These curves are generated with random points from a set range in order to create leaves of different shape. These randomness of these points, or the range they are generated from, could be edited to change the leaf shape. However, a new geometry altogether could be made in the ``L(l)`` section.
136
+
137
+
124
138
125
139
126
140
3. **Changing Bud Geometry:**
141
+
142
+
The call for the production of the buds occurs in the ``grow_one(o)`` section by addicting ``spiked_bud(o.thickness)`` to the ``produce`` call:
143
+
144
+
.. code-block:: python
145
+
146
+
if'Spur'in o.name:
147
+
produce I(o.growth_length, o.thickness, o) bud(ParameterSet(type=o, num_buds=0)) spiked_bud(o.thickness)grow_object(o)
148
+
149
+
The actual bud is produced in the ``spiked_bud`` production section:
127
150
128
151
.. code-block:: python
129
152
@@ -132,41 +155,87 @@ There are many things you may want to modify as you grow your own trees. Here ar
132
155
top_height = r *2
133
156
num_sect =20
134
157
produce @g(Cylinder(r,base_height,1,num_sect))f(base_height)@g(Cone(r,top_height,0,num_sect))
158
+
159
+
This is one of the most basic objects generated on the tree model. As the buds on actual trees are little spikes, the bud geometry is made up of a cone on top of a cylinder. These are both produced with L-Py's basic ``@g`` primitive used to draw PglShapes. The height of the two shapes scale with the radius (provided as the parameter). The ``num_sect`` is used to determine how many sections each shape is made up of, and 20 was chosen as they appear circular without adding too many triangles to the model.
160
+
161
+
135
162
136
163
4. **Changing Branch Profile Curve:**
137
-
164
+
165
+
Every branch on the model has a unique profile curve. This is so the model doesn't appear to be perfectly cylindrical (as if made of PVC pipes). Every branch has its own unique curve that is generated when the branch is originally generated. This can be found in the actual class declaration at the beginning of the code:
Every ``Trunk``, ``Branch``, and ``NonBranch`` object have a their own unique curve associated with them. However this curve is only applied in the ``grow_one(o)`` section:
172
+
138
173
.. code-block:: python
139
174
140
-
# From grow_object(o)
141
175
if'Trunk'in o.name or'Branch'in o.name:
142
-
nproduce SetContour(o.contour)
176
+
nproduce SetContour(o.contour)
143
177
else:
144
-
# set the contour back to a usual circle
145
-
reset_contour()
178
+
reset_contour()
179
+
180
+
This code targets every ``Trunk``, ``Branch``, and ``NonBranch`` object and sets their own curve when growing them. Whenever any other object is passed to the ``grow_object(o)`` function the call to ``reset_contour()`` sets the contour back to a perfect circle to ensure that no curves overlap.
181
+
182
+
The ``create_noisy_circle()`` function is included in the helper.py file. It works by creating a circle out of a given number of points, and then moving those points in the x and y direction according to a given noise factor. The function has two required parameters and two optional parameters. The two required parameters are ``radius`` and ``noise_factor``. The ``radius`` determines the radius of the generated circle. The ``noise_factor`` is used to set a range in which random points will be generated. The points making up the circle will then be moved a random amount in that range. This can be seen in the main ``for`` loop in the function:
183
+
184
+
.. code-block:: python
185
+
186
+
for angle in t:
187
+
# Base circle points
188
+
x = radius * cos(angle)
189
+
y = radius * sin(angle)
190
+
191
+
# Add noise
192
+
noise_x = uniform(-noise_factor, noise_factor)
193
+
noise_y = uniform(-noise_factor, noise_factor)
194
+
195
+
noisy_x = x + noise_x
196
+
noisy_y = y + noise_y
197
+
198
+
points.append((noisy_x, noisy_y))
199
+
200
+
The two optional parameters for the function are ``num_points`` and ``seed``. ``num_points`` is used to determine how many points make up the circle. If no value is given, it defaults to 100. ``seed`` is used to set the randomness of the circles. If a value is given, the random.seed is set to that value. For this model, seeds were not used.
146
201
147
202
5. **Changing Tertiary Branch Curves:**
203
+
204
+
Every tertiary branch on the model follows a unique curve. This curve is generated with the ``create_bezier_curve()`` function which can be found in the helper.py file. The function works by generating four points to be used as guide points for the Bézier curve. There is some control code to make sure that the x points are random but are still generated in a linear fashion.
205
+
206
+
The function takes four optional parameters: ``num_control_points``, ``x_range``, ``y_range``, and ``seed_val``. ``num_control_points`` defaults to four, the standard for Bézier curves. ``x_range`` and ``y_range`` default to a tuples designating the ranges: (0,10) and (-2,2) respectively. ``seed_val`` defaults to ``None``, however in the actual model ``time.time()`` is used as the seed.
148
207
208
+
The actual designation of the curves for the tertiary branches can be seen in the ``bud(t)`` section:
209
+
149
210
.. code-block:: python
150
211
151
-
# From bud(t)
152
212
if'NonTrunk'in new_object.name:
153
-
import time
154
-
curve = create_bezier_curve(seed_val=time.time())
155
-
nproduce [SetGuide(curve, new_object.max_length)
213
+
import time
214
+
curve = create_bezier_curve(seed_val=time.time())
215
+
nproduce [SetGuide(curve, new_object.max_length)
216
+
217
+
A curve is generated with the ``create_bezier_curve()``and it is used as the guide for the ``SetGuide`` function provided by L-Py.
156
218
157
219
6. **Changing color ID system:**
220
+
221
+
Every object on the tree has its own unique color code to act as an ID. The implementation of this can be seen in the ``grow_object(o)`` section:
158
222
159
223
.. code-block:: python
160
224
161
-
# From grow_object(o)
162
225
r, g, b = o.color
163
226
nproduce SetColor(r, g, b)
164
227
165
228
smallest_color = [r, g, b].index(min([r, g, b]))
166
229
o.color[smallest_color] += 1
230
+
231
+
This works by finding the smallest value of the objects RGB code and incrementing it by one. This is to avoid any kind of error where a color value is greater than 255. To get rid of the color IDs, simply comment out the second two lines of the code above.
232
+
233
+
167
234
168
235
7. **Changing Apple and Leaf ratio:**
169
236
237
+
The generation of apples and leaves is random. If something is to grow off of the bud, there is a 90% chance it will be a leaf, and a 10% chance it will be an apple. These percentages are setin the ``Spur``class declaration:
238
+
170
239
.. code-block:: python
171
240
172
241
# From Spur class
@@ -181,6 +250,8 @@ There are many things you may want to modify as you grow your own trees. Here ar
0 commit comments