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