Skip to content

Commit dc772d4

Browse files
committed
[共通] Rect::chamfered() #1268
1 parent 360cd39 commit dc772d4

File tree

4 files changed

+233
-5
lines changed

4 files changed

+233
-5
lines changed

Siv3D/include/Siv3D/Rect.hpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,22 @@ namespace s3d
724724
constexpr RoundRect rounded(double r) const noexcept;
725725

726726
[[nodiscard]]
727-
Polygon rounded(double tl, double tr, double br, double bl) const noexcept;
727+
Polygon rounded(double tl, double tr, double br, double bl) const;
728+
729+
/// @brief 長方形を面取りした Polygon を返します。
730+
/// @param size 面取りの大きさ
731+
/// @return 面取りした Polygon
732+
[[nodiscard]]
733+
Polygon chamfered(double size) const;
734+
735+
/// @brief 長方形を面取りした Polygon を返します。
736+
/// @param tl 左上の面取りの大きさ
737+
/// @param tr 右上の面取りの大きさ
738+
/// @param br 右下の面取りの大きさ
739+
/// @param bl 左下の面取りの大きさ
740+
/// @return 面取りした Polygon
741+
[[nodiscard]]
742+
Polygon chamfered(double tl, double tr, double br, double bl) const;
728743

729744
/// @brief 長方形を Quad として返します。
730745
/// @return 長方形の Quad

Siv3D/include/Siv3D/RectF.hpp

+17-2
Original file line numberDiff line numberDiff line change
@@ -783,8 +783,23 @@ namespace s3d
783783
constexpr RoundRect rounded(double r) const noexcept;
784784

785785
[[nodiscard]]
786-
Polygon rounded(double tl, double tr, double br, double bl) const noexcept;
787-
786+
Polygon rounded(double tl, double tr, double br, double bl) const;
787+
788+
/// @brief 長方形を面取りした Polygon を返します。
789+
/// @param size 面取りの大きさ
790+
/// @return 面取りした Polygon
791+
[[nodiscard]]
792+
Polygon chamfered(double size) const;
793+
794+
/// @brief 長方形を面取りした Polygon を返します。
795+
/// @param tl 左上の面取りの大きさ
796+
/// @param tr 右上の面取りの大きさ
797+
/// @param br 右下の面取りの大きさ
798+
/// @param bl 左下の面取りの大きさ
799+
/// @return 面取りした Polygon
800+
[[nodiscard]]
801+
Polygon chamfered(double tl, double tr, double br, double bl) const;
802+
788803
/// @brief 長方形を Rect として返します。
789804
/// @return 長方形の Rect
790805
[[nodiscard]]

Siv3D/src/Siv3D/Rect/SivRect.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ namespace s3d
8989
return quad;
9090
}
9191

92-
Polygon Rect::rounded(double tl, double tr, double br, double bl) const noexcept
92+
Polygon Rect::rounded(double tl, double tr, double br, double bl) const
9393
{
9494
constexpr double epsilon = 0.001;
9595

@@ -224,6 +224,16 @@ namespace s3d
224224
return Polygon{ vertices };
225225
}
226226

227+
Polygon Rect::chamfered(const double size) const
228+
{
229+
return RectF{ *this }.chamfered(size);
230+
}
231+
232+
Polygon Rect::chamfered(const double tl, const double tr, const double br, const double bl) const
233+
{
234+
return RectF{ *this }.chamfered(tl, tr, br, bl);
235+
}
236+
227237
LineString Rect::outline(const CloseRing closeRing) const
228238
{
229239
if (closeRing)

Siv3D/src/Siv3D/RectF/SivRectF.cpp

+189-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ namespace s3d
8989
return quad;
9090
}
9191

92-
Polygon RectF::rounded(double tl, double tr, double br, double bl) const noexcept
92+
Polygon RectF::rounded(double tl, double tr, double br, double bl) const
9393
{
9494
constexpr double epsilon = 0.001;
9595

@@ -224,6 +224,194 @@ namespace s3d
224224
return Polygon{ vertices };
225225
}
226226

227+
Polygon RectF::chamfered(double s) const
228+
{
229+
if (s <= 0.0)
230+
{
231+
return asPolygon();
232+
}
233+
234+
s = Min(s, (Min(w, h) * 0.5));
235+
236+
Array<Vec2> points;
237+
238+
// 上辺
239+
if ((s * 2.0) < w)
240+
{
241+
points.emplace_back((x + s), y);
242+
points.emplace_back((x + w - s), y);
243+
}
244+
else
245+
{
246+
points.emplace_back((x + w * 0.5), y);
247+
}
248+
249+
// 右辺
250+
if ((s * 2.0) < h)
251+
{
252+
points.emplace_back((x + w), (y + s));
253+
points.emplace_back((x + w), (y + h - s));
254+
}
255+
else
256+
{
257+
points.emplace_back((x + w), (y + h * 0.5));
258+
}
259+
260+
// 下辺
261+
if ((s * 2.0) < w)
262+
{
263+
points.emplace_back((x + w - s), (y + h));
264+
points.emplace_back((x + s), (y + h));
265+
}
266+
else
267+
{
268+
points.emplace_back((x + w * 0.5), (y + h));
269+
}
270+
271+
// 左辺
272+
if ((s * 2.0) < h)
273+
{
274+
points.emplace_back(x, (y + h - s));
275+
points.emplace_back(x, (y + s));
276+
}
277+
else
278+
{
279+
points.emplace_back(x, (y + h * 0.5));
280+
}
281+
282+
Array<TriangleIndex> indices(points.size() - 2);
283+
284+
for (Vertex2D::IndexType i = 0; i < indices.size(); ++i)
285+
{
286+
indices[i] = { 0, static_cast<Vertex2D::IndexType>(i + 1), static_cast<Vertex2D::IndexType>(i + 2) };
287+
}
288+
289+
return Polygon{ points, indices, *this };
290+
}
291+
292+
Polygon RectF::chamfered(double tl, double tr, double br, double bl) const
293+
{
294+
tl = Max(tl, 0.0);
295+
tr = Max(tr, 0.0);
296+
br = Max(br, 0.0);
297+
bl = Max(bl, 0.0);
298+
299+
if (double top = (tl + tr);
300+
w < top)
301+
{
302+
tl *= (w / top);
303+
tr *= (w / top);
304+
}
305+
306+
if (double right = (tr + br);
307+
h < right)
308+
{
309+
tr *= (h / right);
310+
br *= (h / right);
311+
}
312+
313+
if (double bottom = (br + bl);
314+
w < bottom)
315+
{
316+
br *= (w / bottom);
317+
bl *= (w / bottom);
318+
}
319+
320+
if (double left = (bl + tl);
321+
h < left)
322+
{
323+
bl *= (h / left);
324+
tl *= (h / left);
325+
}
326+
327+
Array<Vec2> points;
328+
329+
// 左上
330+
if (tl)
331+
{
332+
const Vec2 p0{ x, (y + tl) };
333+
const Vec2 p1{ (x + tl), y };
334+
points << p0;
335+
points << p1;
336+
}
337+
else
338+
{
339+
points << this->tl();
340+
}
341+
342+
// 右上
343+
if (tr)
344+
{
345+
const Vec2 p0{ (x + w - tr), y };
346+
const Vec2 p1{ (x + w), (y + tr) };
347+
348+
if (points.back() != p0)
349+
{
350+
points << p0;
351+
}
352+
353+
points << p1;
354+
}
355+
else
356+
{
357+
points << this->tr();
358+
}
359+
360+
// 右下
361+
if (br)
362+
{
363+
const Vec2 p0{ (x + w), (y + h - br) };
364+
const Vec2 p1{ (x + w - br), (y + h) };
365+
366+
if (points.back() != p0)
367+
{
368+
points << p0;
369+
}
370+
371+
points << p1;
372+
}
373+
else
374+
{
375+
points << this->br();
376+
}
377+
378+
// 左下
379+
if (bl)
380+
{
381+
const Vec2 p0{ (x + bl), (y + h) };
382+
const Vec2 p1{ x, (y + h - bl) };
383+
384+
if (points.back() != p0)
385+
{
386+
points << p0;
387+
}
388+
389+
if (points.front() != p1)
390+
{
391+
points << p1;
392+
}
393+
}
394+
else
395+
{
396+
const Vec2 p0 = this->bl();
397+
398+
if ((points.back() != p0)
399+
&& (points.front() != p0))
400+
{
401+
points << p0;
402+
}
403+
}
404+
405+
Array<TriangleIndex> indices(points.size() - 2);
406+
407+
for (Vertex2D::IndexType i = 0; i < indices.size(); ++i)
408+
{
409+
indices[i] = { 0, static_cast<Vertex2D::IndexType>(i + 1), static_cast<Vertex2D::IndexType>(i + 2) };
410+
}
411+
412+
return Polygon{ points, indices, *this };
413+
}
414+
227415
LineString RectF::outline(const CloseRing closeRing) const
228416
{
229417
if (closeRing)

0 commit comments

Comments
 (0)