# Heart

I talked about creating a heart in Boolean operations and hull. Creating a heart is admittedly easy; however, you may consider more. Is there any problem with the heart? No. But inconvenience will happen when it incorporates with other models. You probably have to move it to a particular position. Which base are you relying on when moving the heart?

You might have noticed. Some built-in modules in OpenSCAD have the `center` parameter. When it's `true`, the module is centered at (0, 0, 0). One corner of the module is at (0, 0, 0) if the `center` parameter is `false`.

While defining your fundamental modules, you may take the `center` parameter into consideration. The users of the modules, maybe yourself, will appreciate such flexibility. Providing such flexibility, however, needs more information about the geometry of the modules.

# A centered heart

How to center a heart? Let's consider the bilateral symmetry of a heart first. You might remember that a heart is composed of a circle and a square.

``````radius = 10;

rotated_angle = 45;
\$fn = 48;

rotate(-rotated_angle) union() {
square(diameter);
}
}

`````` The radius of the circle is `radius`. The side length of the square is `2 * radius`. The union of them is rotated 45 degrees. The first question is, how to position the under right angle on the y-axis? As the figure shown above, you may move the module `-radius * cos(45)` along the x-axis. Next, invoke the same module again and mirror it. You'll get a heart.

``````radius = 10;

rotated_angle = 45;
\$fn = 48;

rotate(-rotated_angle) union() {
square(diameter);
}
}

}

``````

The `mirror` transformation mirrors the modules on a plane through the origin. As the name shown, it's like a mirror in front of a module. If the mirror laid along the y-z plane and the orientation of the surface is toward the positive direction of the x-axis, the argument to `mirror` is the normal vector of `[1, 0, 0]`.

As the code shown, I extract the same code and define a `heart_sub_component` module, so you don't have to repeat it while mirroring. It also increases the readability. Is the heart centered? Not yet. The vertical center I want is the half of the length between the under right angle and the top of the circle. How long should I move? As the figure shown, the height of the heart is `(4 * radius * sin(45)) + (radius – radius * sin(45))`. That is `3 * radius * sin(45) + radius` after cleaning up the formula. Because the top of the circle is `radius` higher than the origin of the module, you only have to move `(3 * radius * sin(45) + radius) / 2 - radius`, which is `1.5 * radius * sin(45) - 0.5 * radius` after cleaning up. After that, the heart is positioned at the center I want.

``````radius = 10;

rotated_angle = 45;
\$fn = 48;

rotate(-rotated_angle) union() {
square(diameter);
}
}

translate([0, center_offset_y, 0]) union() {
}
}

`````` # A heart in the first quadrant

According to the above figure, if you want to position the heart in the first quadrant, move the heart `radius + radius * cos(45)` along the x-axis and `3 * radius * sin(45)` along the y-axis. It aligns the heart with the bottom of the bounding box at the x-axis and the left of the bounding box at the y-axis.

``````height = 10;

rotated_angle = 45;
\$fn = 48;

rotate(-rotated_angle) union() {
square(diameter);
}
}

module heart(radius, center = false) {
offsetY = center ? 1.5 * radius * sin(45) - 0.5 * radius : 3 * radius * sin(45);

translate([offsetX, offsetY, 0]) union() { You can set default arguments for parameters while defining modules or functions. The `center` parameter of the above code defaults to `false` so `heart(radius)` will not be centered. If you want to center the heart, use `heart(radius, center = true)` or `heart(radius, true)`. I prefer the former for clearness.
In the last example, I transfer `height` into `radius` because it's not intuitive for users to image that the heart is composed of two circles. The height or the width of the heart will be more convenient.