26. Drawing Shapes
Learn to draw various 2D shapes available in Siv3D.
26.1 Circle
- Circles are represented by the
Circle class
Circle can be created as follows:
- Behavior is undefined when the radius is negative
| Code |
Description |
Circle{ X coordinate, Y coordinate, radius } |
Creates a circle from center coordinates and radius |
Circle{ center coordinates, radius } |
Creates a circle from center coordinates and radius |
point.asCircle(radius) |
Creates a circle using a Point value as the center with specified radius |
vec2.asCircle(radius) |
Creates a circle using a Vec2 value as the center with specified radius |
- To draw a circle, use
Circle's .draw()
| Code |
Description |
.draw(color) |
Draws a circle |
.draw(inner color, outer color) |
Draws a gradient circle |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Circle{ 150, 300, 40 }.draw(ColorF{ 0.8 });
Circle{ Vec2{ 400, 300 }, 80 }.draw(ColorF{ 1.0 }, ColorF{ 1.0, 0.6, 0.4 });
Cursor::Pos().asCircle(120).draw(ColorF{ 0.4 });
}
}
26.2 Circle Outline
- To draw a circle outline, use
Circle's .drawFrame()
- Behavior is undefined when thickness is outside the normal range (e.g., negative)
| Code |
Description |
.drawFrame(thickness, color) |
Draws a circle outline |
.drawFrame(thickness, inner color, outer color) |
Draws a gradient circle outline |
.drawFrame(inner thickness, outer thickness, color) |
Draws a circle outline |
.drawFrame(inner thickness, outer thickness, inner color, outer color) |
Draws a gradient circle outline |
- Since
.draw() and .drawFrame() return a reference to the circle itself, you can chain them like circle.draw().drawFrame()

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Circle{ 150, 300, 100 }.drawFrame(10, Palette::Seagreen);
Circle{ 400, 300, 100 }.draw().drawFrame(2, 8, Palette::Seagreen);
Circle{ 650, 300, 100 }.drawFrame(20, ColorF{ 0.0, 0.0 }, ColorF{ 0.0, 1.0 });
}
}
26.3 Pie Shape
- To draw a pie shape, use
Circle's .drawPie()
- The start angle is specified in clockwise radians, with 0 being at 12 o'clock
- The pie angle is specified as the angular size in the clockwise direction
- If negative, the pie is drawn counterclockwise
| Code |
Description |
.drawPie(start angle, pie angle, color) |
Draws a pie shape |
.drawPie(start angle, pie angle, inner color, outer color) |
Draws a gradient pie shape |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Circle{ 150, 300, 120 }.drawPie(0_deg, 90_deg, ColorF{ 1.0 });
Circle{ 400, 300, 120 }.drawPie(-30_deg, 60_deg, ColorF{ 0.25 });
Circle{ 650, 300, 120 }.drawPie(120_deg, 120_deg, ColorF{ 0.1, 0.3, 0.1 }, ColorF{ 0.3, 1.0, 0.6 });
}
}
26.4 Arc
- To draw an arc, use
Circle's .drawArc()
- The start angle is specified in clockwise radians, with 0 being at 12 o'clock
- The arc angle is specified as the angular size in the clockwise direction
- If negative, the arc is drawn counterclockwise
- Behavior is undefined when thickness is outside the normal range (e.g., negative)
| Code |
Description |
.drawArc(start angle, arc angle, inner thickness, outer thickness, color) |
Draws an arc |
.drawArc(start angle, arc angle, inner thickness, outer thickness, inner color, outer color) |
Draws a gradient arc |
.drawArc(LineStyle::RoundCap, start angle, arc angle, inner thickness, outer thickness, color) |
Draws an arc with rounded ends |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Circle{ 150, 300, 120 }.drawArc(0_deg, 240_deg, 2, 2, ColorF{ 0.25 });
Circle{ 400, 300, 120 }.drawArc(-30_deg, 60_deg, 20, 20, ColorF{ 0.0, 0.0 }, ColorF{ 0.0, 1.0 });
Circle{ 650, 300, 120 }.drawArc(LineStyle::RoundCap, 120_deg, 120_deg, 30, 30, ColorF{ 0.1, 0.3, 0.1 });
}
}
26.5 Circle Segment
- To draw a circle segment (chord), use
Circle's .drawSegment() or .drawSegmentFromAngles()
- Angles are specified in radians
| Code |
Description |
.drawSegment(center direction of arc, arc angle, color) |
Draws a circle segment |
.drawSegment(arc start angle, arc angle, color) |
Draws a circle segment |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Circle{ 150, 200, 120 }.drawSegment(0_deg, 60, ColorF{ 0.9 });
Circle{ 400, 200, 120 }.drawSegment(30_deg, 60, ColorF{ 0.9 });
Circle{ 650, 200, 120 }.drawSegment(60_deg, 60, ColorF{ 0.9 });
Circle{ 150, 400, 120 }.drawSegment(120_deg, 60, ColorF{ 0.25 });
Circle{ 400, 400, 120 }.drawSegmentFromAngles(60_deg, 240_deg, ColorF{ 0.25 });
Circle{ 650, 400, 120 }.drawSegmentFromAngles(90_deg, 120_deg, ColorF{ 0.25 });
}
}
26.6 Rectangle
- Rectangles are represented by
Rect or RectF
Rect represents coordinates and sizes with int32 type, while RectF uses double type
- You can use
Size type (alias for Point) and SizeF type (alias for Vec2) to represent sizes
- Rectangles can be created as follows:
- Behavior is undefined when width and height are negative
| Code |
Description |
Rect{ width, height }
RectF{ width, height } |
Creates a rectangle with top-left at (0, 0) |
Rect{ width and height }
RectF{ width and height } |
Creates a rectangle with top-left at (0, 0) |
Rect{ side length }
RectF{ side length } |
Creates a square with top-left at (0, 0) |
Rect{ top-left X, top-left Y, width, height }
RectF{ top-left X, top-left Y, width, height } |
Creates a rectangle |
Rect{ top-left X, top-left Y, width and height }
RectF{ top-left X, top-left Y, width and height } |
Creates a rectangle |
Rect{ top-left X, top-left Y, side length }
RectF{ top-left X, top-left Y, side length } |
Creates a square |
Rect{ top-left coordinates, width, height }
RectF{ top-left coordinates, width, height } |
Creates a rectangle |
Rect{ top-left coordinates, width and height }
RectF{ top-left coordinates, width and height } |
Creates a rectangle |
Rect{ top-left coordinates, side length }
RectF{ top-left coordinates, side length } |
Creates a square |
Rect{ Arg::center(center coordinates), width, height }
RectF{ Arg::center(center coordinates), width, height } |
Creates a rectangle by specifying center coordinates |
Rect{ Arg::center(center coordinates), width and height }
RectF{ Arg::center(center coordinates), width and height } |
Creates a rectangle by specifying center coordinates |
Rect{ Arg::center(center coordinates), side length }
RectF{ Arg::center(center coordinates), side length } |
Creates a square by specifying center coordinates |
Rect::FromPoints(corner coordinates, diagonal corner coordinates)
RectF::FromPoints(corner coordinates, diagonal corner coordinates) |
Creates a rectangle from two given points. A valid rectangle with positive size is created |
- To draw a rectangle, use
Rect or RectF's .draw()
| Code |
Description |
.draw(color) |
Draws a rectangle |
.draw(Arg::top = top color, Arg::bottom = bottom color) |
Draws a vertical gradient rectangle |
.draw(Arg::left = left color, Arg::right = right color) |
Draws a horizontal gradient rectangle |
.draw(Arg::topLeft = top-left color, Arg::bottomRight = bottom-right color) |
Draws a diagonal gradient rectangle from top-left to bottom-right |
.draw(Arg::topRight = top-right color, Arg::bottomLeft = bottom-left color) |
Draws a diagonal gradient rectangle from top-right to bottom-left |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Rect{ 100, 100, 80 }.draw();
RectF{ Vec2{ 200, 100 }, 80 }.draw(HSV{ 220, 0.3, 0.8 });
Rect{ 300, 100, 80, 160 }.draw(ColorF{ 0.5 });
Rect{ Point{ 400, 100 }, Size{ 80, 320 } }.draw(Arg::top(0.8, 0.9, 1.0), Arg::bottom = Palette::Seagreen);
RectF{ 500, 100, SizeF{ 80.0, 320.5 } }.draw();
Rect{ 600, 100, 80, 400 }.draw(Arg::topLeft(1.0), Arg::bottomRight(0.2));
}
}
26.7 Rectangle Outline
- To draw a rectangle outline, use
Rect or RectF's .drawFrame()
- Behavior is undefined when thickness is outside the normal range (e.g., negative)
| Code |
Description |
.drawFrame(thickness, color) |
Draws a rectangle outline |
.drawFrame(thickness, inner color, outer color) |
Draws a gradient rectangle outline |
.drawFrame(inner thickness, outer thickness, color) |
Draws a rectangle outline |
.drawFrame(inner thickness, outer thickness, inner color, outer color) |
Draws a gradient rectangle outline |
.drawFrame(thickness, Arg::top = top color, Arg::bottom = bottom color) |
Draws a vertical gradient rectangle outline |
.drawFrame(inner thickness, outer thickness, Arg::top = top color, Arg::bottom = bottom color) |
Draws a vertical gradient rectangle outline |
- Since
.draw() and .drawFrame() return a reference to the rectangle itself, you can chain them like rect.draw().drawFrame()

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Rect{ 100, 100, 80 }.drawFrame(2);
Rect{ 200, 100, 80 }
.draw()
.drawFrame(2, 8, ColorF{ 0.1 });
Rect{ 300, 100, 80, 160 }.drawFrame(10, 0, ColorF{ 0.0, 0.0 }, ColorF{ 0.0, 1.0 });
Rect{ 400, 100, 80, 160 }
.draw(Arg::top(1.0, 0.8, 0.0), Arg::bottom = Palette::Red)
.drawFrame(2, ColorF{ 0.1 });
Rect{ 500, 100, 80, 320 }
.drawFrame(3, 0)
.drawFrame(0, 3, ColorF{ 0.1 });
Rect{ 600, 100, 80, 320 }
.drawFrame(3, 0, ColorF{ 0.1 })
.drawFrame(0, 3, Arg::top(0.1), Arg::bottom(0.9));
}
}
26.8 Rounded Rectangle
- Rounded rectangles are represented by
RoundRect
RoundRect can be created as follows:
- Behavior is undefined when size is negative or corner radius is invalid
| Code |
Description |
RoundRect{ top-left X, top-left Y, width, height, corner radius } |
Creates a rounded rectangle |
RoundRect{ top-left coordinates, width, height, corner radius } |
Creates a rounded rectangle |
RoundRect{ top-left coordinates, width and height, corner radius } |
Creates a rounded rectangle |
RoundRect{ Rect{ ... }, corner radius } |
Creates a rounded rectangle |
RoundRect{ RectF{ ... }, corner radius } |
Creates a rounded rectangle |
RoundRect{ Arg::center(center coordinates), width, height, corner radius } |
Creates a rounded rectangle by specifying center coordinates |
RoundRect{ Arg::center(center coordinates), width and height, corner radius } |
Creates a rounded rectangle by specifying center coordinates |
rect.rounded(corner radius) |
Creates a rounded rectangle from a rectangle (Rect or RectF) |
- To draw a rounded rectangle, use
RoundRect's .draw()
| Code |
Description |
.draw(color) |
Draws a rounded rectangle |
.draw(Arg::top = top color, Arg::bottom = bottom color) |
Draws a vertical gradient rounded rectangle |
- To draw a rounded rectangle outline, use
RoundRect's .drawFrame()
| Code |
Description |
.drawFrame(thickness, color) |
Draws a rounded rectangle outline |
.drawFrame(inner thickness, outer thickness, color) |
Draws a rounded rectangle outline |
.drawFrame(thickness, Arg::top = top color, Arg::bottom = bottom color) |
Draws a vertical gradient rounded rectangle outline |
.drawFrame(inner thickness, outer thickness, Arg::top = top color, Arg::bottom = bottom color) |
Draws a vertical gradient rounded rectangle outline |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Rect rect{ 100, 300, 500, 200 };
while (System::Update())
{
RoundRect{ 100, 100, 200, 100, 20 }.draw();
RoundRect{ Arg::center(600, 150), 200, 80, 10 }.draw();
rect.rounded(40).draw(ColorF{ 0.2 });
}
}
26.9 Rectangle with Some Rounded Corners
- There is no dedicated class for rectangles with partially rounded corners; they are represented using the general polygon class
Polygon
- A
Polygon representing a rectangle with some rounded corners can be created as follows:
- Behavior is undefined when curve radius is invalid
| Code |
Description |
rect.rounded(tl, tr, br, bl) |
Creates a rectangle with some rounded corners from a rectangle (Rect or RectF) |
tl is the top-left corner radius, tr is the top-right corner radius, br is the bottom-right corner radius, and bl is the bottom-left corner radius
- To draw a rectangle with some rounded corners, use
Polygon's .draw()

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Rect{ 100, 100, 200, 100 }
.rounded(40, 0, 0, 0).draw();
Rect{ 400, 100, 200, 100 }
.rounded(40, 40, 0, 0).draw();
Rect{ 100, 300, 200, 200 }
.rounded(40, 0, 40, 0).draw(ColorF{ 0.2 });
Rect{ 400, 300, 200, 200 }
.rounded(20, 40, 60, 80).draw(ColorF{ 0.2 });
}
}
26.10 Line Segment
- Line segments are represented by
Line
Line can be created as follows:
| Code |
Description |
Line{ start X, start Y, end X, end Y } |
Creates a line segment |
Line{ start coordinates, end coordinates } |
Creates a line segment |
Line{ start, end X, end Y } |
Creates a line segment |
Line{ start X, start Y, end } |
Creates a line segment |
Line{ start X, start Y, Arg::angle = direction, length } |
Creates a line segment |
Line{ start coordinates, Arg::angle = direction, length } |
Creates a line segment |
Line{ start X, start Y, Arg::direction = direction vector } |
Creates a line segment |
Line{ start coordinates, Arg::direction = direction vector } |
Creates a line segment |
rect.top(), rect.bottom(), rect.left(), rect.right() |
Creates line segments representing the top, bottom, left, or right edge of a rectangle (Rect or RectF) |
- To draw a line segment, use
Line's .draw()
| Code |
Description |
.draw(color) |
Draws a line segment |
.draw(start color, end color) |
Draws a gradient line segment |
.draw(thickness, color) |
Draws a line segment |
.draw(thickness, start color, end color) |
Draws a gradient line segment |
.draw(line style, thickness, color) |
Draws a line segment |
.draw(line style, thickness, start color, end color) |
Draws a gradient line segment |
- You can specify one of the following line styles:
| Code |
Description |
LineStyle::SquareCap |
Square ends (default) |
LineStyle::Uncapped |
Flat ends |
LineStyle::RoundCap |
Rounded ends |
LineStyle::SquareDot |
Square dotted line |
LineStyle::RoundDot |
Round dotted line |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Line{ 100, 100, 400, 150 }.draw(4);
Line{ 400, 300, Cursor::Pos() }.draw(10, Palette::Seagreen);
Line{ 100, 400, 700, 400 }.draw(12, Palette::Orange);
Line{ 100, 450, 700, 450 }.draw(LineStyle::RoundCap, 12, ColorF{ 0.2 });
Line{ 100, 500, 700, 500 }.draw(LineStyle::SquareDot, 12, ColorF{ 0.2 });
Line{ 100, 550, 700, 550 }.draw(LineStyle::RoundDot, 12, ColorF{ 0.2 });
}
}
- When drawing horizontal or vertical line segments, consider using
Rect or RectF
- Drawing as a rectangle is advantageous in terms of quality and performance
26.11 Arrow
- There is no dedicated class for arrows; use
Line's .drawArrow() or .drawDoubleHeadedArrow() to draw them
- Single-directional arrows are drawn from the
Line's start point toward the end point
| Code |
Description |
.drawArrow(line width, triangle width and height, color) |
Draws a single-directional arrow |
.drawDoubleHeadedArrow(line width, triangle width and height, color) |
Draws a double-headed arrow |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Line{ 50, 200, 200, 250 }
.drawArrow(3, SizeF{ 20, 20 }, ColorF{ 0.2 });
Line{ 350, 450, 450, 100 }
.drawArrow(10, SizeF{ 40, 80 }, ColorF{ 0.2 });
Line{ 600, 100, 700, 400 }
.drawDoubleHeadedArrow(8, SizeF{ 30, 30 }, ColorF{ 0.2 });
}
}
26.12 Triangle
- Triangles are represented by
Triangle
Triangle can be created as follows:
| Code |
Description |
Triangle{ side length } |
Creates an equilateral triangle with center at (0, 0) and specified side length |
Triangle{ side length, rotation angle } |
Creates a rotated equilateral triangle with center at (0, 0) and specified side length |
Triangle{ center X, center Y, side length } |
Creates an equilateral triangle with specified center and side length |
Triangle{ center coordinates, side length } |
Creates an equilateral triangle with specified center and side length |
Triangle{ center X, center Y, side length, rotation angle } |
Creates a rotated equilateral triangle with specified center and side length |
Triangle{ center coordinates, side length, rotation angle } |
Creates a rotated equilateral triangle with specified center and side length |
Triangle{ x0, y0, x1, y1, x2, y2 } |
Creates a triangle by specifying three vertices clockwise |
Triangle{ pos0, pos1, pos2 } |
Creates a triangle by specifying three vertices clockwise |
Triangle::FromPoints(pos0, pos1, pos2) |
Creates a triangle by specifying three vertices. Vertex order is adjusted to create a valid triangle |
Note
- Triangles with vertices specified counterclockwise can be drawn but other features (collision detection, etc.) may not work correctly
- To draw a triangle, use
Triangle's .draw()
| Code |
Description |
.draw(color) |
Draws a triangle |
.draw(color0, color1, color2) |
Draws a triangle with specified colors for the three vertices |
- To draw a triangle outline, use
Triangle's .drawFrame()
| Code |
Description |
.drawFrame(thickness, color) |
Draws a triangle outline |
.drawFrame(inner thickness, outer thickness, color) |
Draws a triangle outline |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
// Draw a triangle composed of coordinates (100, 100), (400, 300), (100, 300)
Triangle{ 100, 100, 400, 300, 100, 300 }.draw();
// Draw a triangle with center at (300, 100) and sides of 80px
Triangle{ 300, 100, 80 }.draw(Palette::Orange);
// Draw rotated 15° clockwise
Triangle{ 400, 100, 80, 15_deg }.draw(Palette::Seagreen);
// Draw rotated 30° clockwise
Triangle{ 500, 100, 80, 30_deg }.draw(HSV{ 0 }, HSV{ 120 }, HSV{ 240 });
// Specify three vertex coordinates with Point or Vec2 types
Triangle{ Cursor::Pos(), Vec2{ 700, 500 }, Vec2{ 100, 500 } }.draw(ColorF{ 0.2 });
}
}
26.13 Convex Quadrilateral
- Convex quadrilaterals with 4 vertices are represented by
Quad
- Trapezoids and parallelograms are represented by
Quad
- Unlike
Rect and RectF whose edges are parallel to the X and Y axes, Quad has no such constraint
Quad can be created as follows:
| Code |
Description |
Quad{ vertex0, vertex1, vertex2, vertex3 } |
Creates a quadrilateral by specifying four vertices |
Quad{ x0, y0, x1, y1, x2, y2, x3, y3 } |
Creates a quadrilateral by specifying four vertices |
Quad{ Rect{ ... } } |
Creates a quadrilateral from a rectangle |
Quad{ RectF{ ... } } |
Creates a quadrilateral from a rectangle |
rect.rotated(rotation angle) |
Creates a quadrilateral by rotating a rectangle (Rect or RectF) |
rect.rotatedAt(rotation center, rotation angle) |
Creates a quadrilateral by rotating a rectangle (Rect or RectF) |
rect.shearedX(slide distance) |
Creates a parallelogram by sliding the top and bottom edges of a rectangle (Rect or RectF) in the X direction |
rect.shearedY(slide distance) |
Creates a parallelogram by sliding the left and right edges of a rectangle (Rect or RectF) in the Y direction |
rect.skewedX(tilt angle) |
Creates a parallelogram by tilting the left and right edges of a rectangle (Rect or RectF) |
rect.skewedY(tilt angle) |
Creates a parallelogram by tilting the top and bottom edges of a rectangle (Rect or RectF) |
Note
- Behavior is undefined when the four vertices are counterclockwise or form a concave shape

- To draw a quadrilateral, use
Quad's .draw()
| Code |
Description |
.draw(color) |
Draws a quadrilateral |
.draw(color0, color1, color2, color3) |
Draws a quadrilateral with specified colors for the four vertices |
- To draw a quadrilateral outline, use
Quad's .drawFrame()
| Code |
Description |
.drawFrame(thickness, color) |
Draws a quadrilateral outline |
.drawFrame(inner thickness, outer thickness, color) |
Draws a quadrilateral outline |
26.13.1 Specifying 4 Vertices
- Create a
Quad by specifying four vertex coordinates

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Quad{ Vec2{ 100, 100 }, Vec2{ 150, 100 }, Vec2{ 300, 300 }, Vec2{ 100, 300 } }.draw();
Quad{ 300, 400, 500, 100, 600, 200, 500, 500 }.draw(ColorF{ 0.2 });
}
}
26.13.2 Rotating a Rectangle
- Create a
Quad by rotating a rectangle

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Rect rect{ 150, 200, 400, 100 };
double angle = 0_deg;
while (System::Update())
{
angle += (Scene::DeltaTime() * 30_deg);
rect.draw();
// The center of the rectangle is the rotation axis
rect.rotated(angle).draw(Palette::Seagreen);
// The top-left of the rectangle is the rotation axis
rect.rotatedAt(rect.pos, angle).draw(ColorF{ 0.2 });
}
}
26.13.3 Sliding and Skewing a Rectangle
- Create a
Quad by sliding or skewing the edges of a rectangle

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
// Draw a parallelogram with edges slid 30px in the X direction
Rect{ 100, 100, 200, 150 }.drawFrame(4, 0)
.shearedX(30).draw(ColorF{ 0.2 });
// Draw a parallelogram with edges slid -50px in the Y direction
Rect{ 500, 100, 200, 150 }.drawFrame(4, 0)
.shearedY(-50).draw(ColorF{ 0.2 });
// Draw a parallelogram with left and right edges tilted 30°
Rect{ 100, 350, 200, 150 }.drawFrame(4, 0)
.skewedX(30_deg).draw(Palette::Seagreen);
// Draw a parallelogram with top and bottom edges tilted -10°
Rect{ 500, 350, 200, 150 }.drawFrame(4, 0)
.skewedY(-10_deg).draw(Palette::Seagreen);
}
}
26.14 Ellipse
- Ellipses are represented by
Ellipse
- Tilted ellipses cannot be represented.
- To draw a tilted ellipse, consider using
Transformer2D from Tutorial XX or approximating with Polygon
Ellipse can be created as follows:
| Code |
Description |
Ellipse{ center X, center Y, X-axis radius, Y-axis radius } |
Creates an ellipse |
Ellipse{ center coordinates, X-axis radius, Y-axis radius } |
Creates an ellipse |
Ellipse{ center X, center Y, X and Y-axis radius } |
Creates an ellipse |
Ellipse{ center coordinates, X and Y-axis radius } |
Creates an ellipse |
Ellipse{ Circle{ ... } } |
Creates an ellipse |
Ellipse{ Rect{ ... } } |
Creates an ellipse inscribed in a rectangle |
Ellipse{ RectF{ ... } } |
Creates an ellipse inscribed in a rectangle |
- To draw an ellipse, use
Ellipse's .draw()
| Code |
Description |
.draw(color) |
Draws an ellipse |
.draw(inner color, outer color) |
Draws a gradient ellipse |
- To draw an ellipse outline, use
Ellipse's .drawFrame()
| Code |
Description |
.drawFrame(thickness, color) |
Draws an ellipse outline |
.drawFrame(inner thickness, outer thickness, color) |
Draws an ellipse outline |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Ellipse{ 300, 200, 200, 100 }.draw();
Ellipse{ 600, 400, 50, 150 }.draw(ColorF{ 0.2 });
}
}
26.15 Common Shapes
- Functions are provided to draw commonly used shapes in a single line
- These functions return
Shape2D objects containing vertex arrays
| Code |
Shape |
Shape2D::Cross(radius, thickness, center = { 0, 0 }, rotation = 0.0) |
✖ mark |
Shape2D::Plus(radius, thickness, center = { 0, 0 }, rotation = 0.0) |
+ mark |
Shape2D::Pentagon(radius, center = { 0, 0 }, rotation = 0.0) |
Regular pentagon |
Shape2D::Hexagon(radius, center = { 0, 0 }, rotation = 0.0) |
Regular hexagon |
Shape2D::Ngon(number of sides, radius, center = { 0, 0 }, rotation = 0.0) |
Regular N-gon |
Shape2D::Star(radius, center = { 0, 0 }, rotation = 0.0) |
Pentagram |
Shape2D::NStar(number of points, outer radius, inner radius, center = { 0, 0 }, rotation = 0.0) |
Star |
Shape2D::Arrow(start, end, thickness, triangle width and height) |
Arrow |
Shape2D::Arrow(line segment, thickness, triangle width and height) |
Arrow |
Shape2D::DoubleHeadedArrow(start, end, thickness, triangle width and height) |
Double-headed arrow |
Shape2D::DoubleHeadedArrow(line segment, thickness, triangle width and height) |
Double-headed arrow |
Shape2D::Rhombus(width, height, center = { 0, 0 }, rotation = 0.0) |
Rhombus |
Shape2D::RectBalloon(rectangle, target coordinates, root ratio = 0.5) |
Rectangle speech bubble |
Shape2D::Stairs(base coordinates, width, height, number of steps, go up to the right = true) |
Staircase shape |
Shape2D::Heart(radius, center = { 0, 0 }, rotation = 0.0) |
Heart shape |
Shape2D::Squircle(radius, center, quality) |
Between square and circle |
Shape2D::Astroid(center, circumscribed ellipse X-axis radius, circumscribed ellipse Y-axis radius, rotation = 0.0) |
Astroid |
- To draw these shapes, use
Shape2D's .draw()
| Code |
Description |
.draw(color) |
Draws the shape |
- To draw the outline of these shapes, use
Shape2D's .drawFrame()
| Code |
Description |
.drawFrame(thickness, color) |
Draws the shape outline |

# include <Siv3D.hpp>
void Main()
{
// Change window size to 1280x720
Window::Resize(1280, 720);
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Shape2D::Cross(80, 10, Vec2{ 100, 100 }).draw();
Shape2D::Plus(80, 10, Vec2{ 300, 100 }).draw();
Shape2D::Pentagon(80, Vec2{ 500, 100 }).draw();
Shape2D::Hexagon(80, Vec2{ 700, 100 }).draw();
Shape2D::Hexagon(80, Vec2{ 900, 100 }, 30_deg).draw();
Shape2D::Hexagon(80, Vec2{ 1100, 100 }, 30_deg).drawFrame(4, ColorF{ 0.2 });
Shape2D::Ngon(10, 80, Vec2{ 100, 300 }).draw();
Shape2D::Star(80, Vec2{ 300, 300 }).draw();
Shape2D::NStar(10, 80, 60, Vec2{ 500, 300 }).draw();
Shape2D::Arrow(Line{ 640, 340, 760, 260 }, 20, Vec2{ 40, 30 }).draw();
Shape2D::DoubleHeadedArrow(Line{ 840, 340, 960, 260 }, 20, Vec2{ 40, 30 }).draw();
Shape2D::Rhombus(160, 120, Vec2{ 1100, 300 }).draw();
Shape2D::RectBalloon(RectF{ 20, 420, 160, 120 }, Vec2{ 20, 580 }, 0.5).draw();
Shape2D::Stairs(Vec2{ 360, 560 }, 120, 120, 4).draw();
Shape2D::Heart(80, Vec2{ 500, 500 }).draw();
Shape2D::Squircle(60, Vec2{ 700, 500 }, 64).draw();
Shape2D::Astroid(Vec2{ 900, 500 }, 60, 80).draw();
}
}
26.16 Free Polygon
- Arbitrary polygons are represented by
Polygon
Polygon can be created as follows:
- Must have at least 3 vertices, with the outer perimeter specified clockwise and holes specified counterclockwise
| Code |
Description |
Polygon{ vertex0, vertex1, ... } |
Creates a polygon |
Polygon{ Array<Vec2>{ ... } } |
Creates a polygon |
Polygon{ Array<Vec2>{ ... }, Array<Array<Vec2>>{ ... } } |
Creates a polygon with holes |
Polygon{ Shape2D } |
Creates a polygon from Shape2D |
circle.asPolygon(quality) |
Converts a circle to a polygon |
ellipse.asPolygon(quality) |
Converts an ellipse to a polygon |
rect.asPolygon() |
Converts a rectangle (Rect or RectF) to a polygon |
roundRect.asPolygon() |
Converts a rounded rectangle (RoundRect) to a polygon |
triangle.asPolygon() |
Converts a triangle (Triangle) to a polygon |
quad.asPolygon() |
Converts a quadrilateral (Quad) to a polygon |
shape2D.asPolygon() |
Converts Shape2D to a polygon |
- Creating
Polygon objects has runtime costs for memory allocation and triangulation calculations
- In particular, those with many vertices should be avoided inside loops.
- To draw a polygon, use
Polygon's .draw()
| Code |
Description |
.draw(color) |
Draws a polygon |
.draw(X offset, Y offset, color) |
Draws a polygon |
.draw(offset, color) |
Draws a polygon |
- To draw a polygon outline, use
Polygon's .drawFrame()
| Code |
Description |
.drawFrame(thickness, color) |
Draws a polygon outline |
.drawFrame(X offset, Y offset, thickness, color) |
Draws a polygon outline |
.drawFrame(offset, thickness, color) |
Draws a polygon outline |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
// Polygon
const Polygon polygon1
{
Vec2{ 200, 100 }, Vec2{ 380, 300 }, Vec2{ 300, 500 }, Vec2{ 200, 400 }, Vec2{ 100, 500 }, Vec2{ 20, 300 }
};
// Polygon with hole
const Polygon polygon2
{
// Outer perimeter
{ Vec2{ 600, 100 }, Vec2{ 780, 300 }, Vec2{ 700, 500 }, Vec2{ 600, 400 }, Vec2{ 500, 500 }, Vec2{ 420, 300 } },
// Hole
{ { Vec2{ 620, 250 }, Vec2{ 580, 250 }, Vec2{ 550, 350 }, Vec2{ 650, 350 } } }
};
while (System::Update())
{
polygon1.draw();
polygon2.draw(ColorF{ 0.2 });
}
}
- If you want to draw shapes with less runtime cost than
Polygon, use lower-level classes like Shape2D or Buffer2D
- With
Shape2D, you need to prepare index arrays in addition to vertex arrays yourself
- With
Buffer2D, you also need to prepare UV coordinates for texture mapping
- Neither is covered in this chapter
26.17 Continuous Line Segments
- Continuous line segments are represented by
LineString
LineString can be created as follows:
| Code |
Description |
LineString{ vertex0, vertex1, ... } |
Creates continuous line segments |
LineString{ Array<Point>{ ... } } |
Creates continuous line segments |
LineString{ Array<Vec2>{ ... } } |
Creates continuous line segments |
- To draw continuous line segments, use
LineString's .draw() or .drawClosed()
.draw() does not connect the end point to the start point
.drawClosed() connects the end point to the start point
| Code |
Description |
.draw(thickness, color) |
Draws continuous line segments |
.draw(LineStyle::RoundCap, thickness, color) |
Draws continuous line segments with rounded ends |
.drawClosed(thickness, color) |
Draws continuous line segments (connecting end to start) |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const LineString ls1
{
Vec2{ 100, 60 }, Vec2{ 400, 140 },
Vec2{ 100, 220 }, Vec2{ 400, 300 },
Vec2{ 100, 380 }, Vec2{ 400, 460 },
Vec2{ 100, 540 }
};
const LineString ls2
{
Vec2{ 500, 100 }, Vec2{ 700, 200 },
Vec2{ 600, 500 },
};
while (System::Update())
{
ls1.draw(6);
ls2.drawClosed(8, ColorF{ 0.2 });
}
}
LineString is essentially Array<Vec2>
- Array-like operations are possible

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
LineString points;
while (System::Update())
{
// If left-clicked
if (MouseL.down())
{
// Add a point
points << Cursor::Pos();
}
// Draw continuous line segments
points.draw(8, ColorF{ 0.2 });
// For each point
for (const auto& point : points)
{
// Draw a circle
point.asCircle(10).draw();
}
}
}
26.18 Spline Curves
- Catmull-Rom spline curves are represented by
Spline2D
- Catmull-Rom spline curves always pass through the specified control points
Spline2D can be created as follows:
- Specifying
CloseRing::Yes creates a closed ring connecting the end to the start
| Code |
Description |
Spline2D{ Array<Vec2>{ ... } } |
Creates a Catmull-Rom spline curve |
Spline2D{ LineString{ ... } } |
Creates a Catmull-Rom spline curve |
Spline2D{ Array<Vec2>{ ... }, CloseRing::Yes } |
Creates a Catmull-Rom spline curve (ring) |
- To draw a spline curve, use
Spline2D's .draw()
| Code |
Description |
.draw(color, quality = 24) |
Draws a spline curve |
.draw(thickness, color, quality = 24) |
Draws a spline curve |
.draw(LineStyle::RoundCap, thickness, color, quality = 24) |
Draws a spline curve with rounded ends |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const LineString ls
{
Vec2{ 100, 60 }, Vec2{ 400, 140 },
Vec2{ 100, 220 }, Vec2{ 400, 300 },
Vec2{ 100, 380 }, Vec2{ 400, 460 },
Vec2{ 100, 540 }
};
const Spline2D spline1{ ls };
const Spline2D spline2
{
{ Vec2{ 500, 100 }, Vec2{ 700, 200 }, Vec2{ 600, 500 } },
CloseRing::Yes
};
while (System::Update())
{
spline1.draw(6);
spline2.draw(8, ColorF{ 0.2 });
}
}
26.19 Bezier Curves
- Quadratic Bezier curves are represented by
Bezier2, and cubic Bezier curves by Bezier3
- Bezier curves can be created as follows:
| Code |
Description |
Bezier2{ start, control point, end } |
Creates a quadratic Bezier curve |
Bezier3{ start, control point 1, control point 2, end } |
Creates a cubic Bezier curve |
- To draw a Bezier curve, use
Bezier2 or Bezier3's .draw()
| Code |
Description |
.draw(color, quality = 24) |
Draws a Bezier curve |
.draw(thickness, color, quality = 24) |
Draws a Bezier curve |
.draw(LineStyle::RoundCap, thickness, color, quality = 24) |
Draws a Bezier curve with rounded ends |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
// Quadratic Bezier curve
Bezier2{ Vec2{ 100, 400 }, Vec2{ 100, 250 }, Vec2{ 300, 100 } }.draw(6);
// Cubic Bezier curve
Bezier3{ Vec2{ 300, 400 }, Vec2{ 400, 400 }, Vec2{ 400, 100 }, Vec2{ 500, 100 }}.draw(8, ColorF{ 0.2 });
}
}
26.20 Shape Shadows
Circle, Rect, RectF, and RoundRect have a .drawShadow() member function to draw shadows
- The first argument specifies the shadow position offset, the second argument the blur size, the third argument the shadow size offset, and the fourth argument the shadow color
- Since shadows fill areas that would be hidden by the shape, you need to draw the shape on top after drawing the shadow
| Code |
Description |
.drawShadow(shadow position offset, blur size, shadow size offset, shadow color) |
Draws a shadow for shapes (Circle, Rect, RectF, RoundRect) |
- Since
.drawShadow() returns a reference to the shape itself, you can chain .draw() after it

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
Rect{ 100, 50, 150, 200 }
.drawShadow(Vec2{ 2, 2 }, 8, 1)
.draw();
Rect{ 300, 50, 150, 200 }
.drawShadow(Vec2{ 4, 4 }, 16, 1.5)
.draw();
Rect{ 500, 50, 150, 200 }
.drawShadow(Vec2{ 6, 6 }, 24, 2)
.draw();
Circle{ 100, 400, 50 }
.drawShadow(Vec2{ 0, 4 }, 10, 3)
.draw(ColorF{ 0.6, 0.8, 0.7 });
Circle{ 300, 400, 50 }
.drawShadow(Vec2{ 0, -4 }, 10, 3)
.draw(ColorF{ 0.5, 0.7, 0.6 });
RoundRect{ 450, 350, 100, 100, 20 }
.drawShadow(Vec2{ 2, 2 }, 8, 0)
.draw();
RoundRect{ 650, 350, 100, 100, 20 }
.drawShadow(Vec2{ 2, 2 }, 12, 0)
.draw();
}
}
26.21 Polygon Wireframe Display
Polygon can display wireframes with .drawWireframe()
- Wireframe display draws all edges of the triangles that make up the polygon
| Code |
Description |
.drawWireframe(thickness, color) |
Draws a polygon wireframe |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Polygon polygon1
{
Vec2{ 200, 100 }, Vec2{ 380, 300 }, Vec2{ 300, 500 }, Vec2{ 200, 400 }, Vec2{ 100, 500 }, Vec2{ 20, 300 }
};
const Polygon polygon2
{
{ Vec2{ 600, 100 }, Vec2{ 780, 300 }, Vec2{ 700, 500 }, Vec2{ 600, 400 }, Vec2{ 500, 500 }, Vec2{ 420, 300 } },
{ { Vec2{ 620, 250 }, Vec2{ 580, 250 }, Vec2{ 550, 350 }, Vec2{ 650, 350 } } }
};
while (System::Update())
{
polygon1.draw();
polygon1.drawWireframe(2, ColorF{ 0.2 });
polygon2.draw(ColorF{ 0.2 });
polygon2.drawWireframe(2);
}
}