""" name: "canadian_flag.py" title: "Canadian Flag blowing in the wind" authors: "Gumyr" license: "http://www.apache.org/licenses/LICENSE-2.0" created: "2023-02-23" modified: "2023-07-31" description: | A Canadian Flag blowing in the wind created by projecting planar faces onto a non-planar face (the_wind). This example also demonstrates building complex lines that snap to existing features. has_builder_mode: true has_algebra_mode: true image_files: - "example_canadian_flag_01.png" - "example_canadian_flag_02.png" - "example_canadian_flag_03.png" """ # [Imports] from math import sin, cos, pi from build123d import * from ocp_vscode import show_object, show # [Parameters] # Canadian Flags have a 2:1 aspect ratio height = 50 width = 2 * height wave_amplitude = 3 # [Code] def surface(amplitude, u, v): """Calculate the surface displacement of the flag at a given position""" return v * amplitude / 20 * cos(3.5 * pi * u) + amplitude / 10 * v * sin( 1.1 * pi * v ) # Note that the surface to project on must be a little larger than the faces # being projected onto it to create valid projected faces the_wind = Face.make_surface_from_array_of_points( [ [ Vector( width * (v * 1.1 / 40 - 0.05), height * (u * 1.2 / 40 - 0.1), height * surface(wave_amplitude, u / 40, v / 40) / 2, ) for u in range(41) ] for v in range(41) ] ) with BuildSketch(Plane.XY.offset(10)) as west_field_builder: Rectangle(width / 4, height, align=(Align.MIN, Align.MIN)) west_field_planar = west_field_builder.sketch.faces()[0] east_field_planar = west_field_planar.mirror(Plane.YZ.offset(width / 2)) with BuildSketch(Plane((width / 2, 0, 10))) as center_field_builder: Rectangle(width / 2, height, align=(Align.CENTER, Align.MIN)) with BuildSketch( Plane((width / 2, 0, 10)), mode=Mode.SUBTRACT ) as maple_leaf_builder: with BuildLine() as outline: l1 = Polyline((0.0000, 0.0771), (0.0187, 0.0771), (0.0094, 0.2569)) l2 = Polyline((0.0325, 0.2773), (0.2115, 0.2458), (0.1873, 0.3125)) RadiusArc(l1 @ 1, l2 @ 0, 0.0271) l3 = Polyline((0.1915, 0.3277), (0.3875, 0.4865), (0.3433, 0.5071)) TangentArc(l2 @ 1, l3 @ 0, tangent=l2 % 1) l4 = Polyline((0.3362, 0.5235), (0.375, 0.6427), (0.2621, 0.6188)) SagittaArc(l3 @ 1, l4 @ 0, 0.003) l5 = Polyline((0.2469, 0.6267), (0.225, 0.6781), (0.1369, 0.5835)) ThreePointArc( l4 @ 1, (l4 @ 1 + l5 @ 0) * 0.5 + Vector(-0.002, -0.002), l5 @ 0 ) l6 = Polyline((0.1138, 0.5954), (0.1562, 0.8146), (0.0881, 0.7752)) Spline( l5 @ 1, l6 @ 0, tangents=(l5 % 1, l6 % 0), tangent_scalars=(2, 2), ) l7 = Line((0.0692, 0.7808), (0.0000, 0.9167)) TangentArc(l6 @ 1, l7 @ 0, tangent=l6 % 1) mirror(outline.edges(), Plane.YZ) make_face() scale(by=height) maple_leaf_planar = maple_leaf_builder.sketch.faces()[0] center_field_planar = center_field_builder.sketch.faces()[0] west_field = west_field_planar.project_to_shape(the_wind, (0, 0, -1))[0] west_field.color = Color("red") east_field = east_field_planar.project_to_shape(the_wind, (0, 0, -1))[0] east_field.color = Color("red") center_field = center_field_planar.project_to_shape(the_wind, (0, 0, -1))[0] center_field.color = Color("white") maple_leaf = maple_leaf_planar.project_to_shape(the_wind, (0, 0, -1))[0] maple_leaf.color = Color("red") canadian_flag = Compound(children=[west_field, east_field, center_field, maple_leaf]) show(Rot(90, 0, 0) * canadian_flag) # [End]