Skip to content

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);
	}
}