src/circularprimitive.h

changeset 232
8efa3a33172e
child 247
07ad61423c3c
equal deleted inserted replaced
231:a9bf6bab5ea2 232:8efa3a33172e
1 #pragma once
2 #include <glm/gtc/matrix_transform.hpp>
3 #include "basics.h"
4 #include "model.h"
5 #include "ldrawalgorithm.h"
6
7 template<typename Fn>
8 void rasterize(const CircularPrimitive& circ, Fn&& fn)
9 {
10 std::vector<ModelElement> result;
11 const auto xform = [&circ](const glm::vec2& p, float y){
12 return glm::vec3{circ.transformation * glm::vec4{p.x, y, p.y, 1}};
13 };
14 const glm::vec3 origin = xform({0, 0}, 0);
15 switch(circ.type) {
16 case CircularPrimitive::Circle:
17 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
18 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
19 fn(edge(xform(p1, 0), xform(p2, 0)));
20 });
21 break;
22 case CircularPrimitive::Disc:
23 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
24 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
25 fn(triangle(origin, xform(p1, 0), xform(p2, 0)));
26 });
27 break;
28 case CircularPrimitive::Cylinder:
29 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
30 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
31 fn(quadrilateral(xform(p1, 1), xform(p2, 1), xform(p2, 0), xform(p1, 0)));
32 });
33 break;
34 case CircularPrimitive::CylinderOpen:
35 rasterize(CircularPrimitive{
36 .type = CircularPrimitive::Cylinder,
37 .fraction = circ.fraction,
38 .transformation = circ.transformation,
39 }, fn);
40 rasterize(CircularPrimitive{
41 .type = CircularPrimitive::Circle,
42 .fraction = circ.fraction,
43 .transformation = circ.transformation,
44 }, fn);
45 rasterize(CircularPrimitive{
46 .type = CircularPrimitive::Circle,
47 .fraction = circ.fraction,
48 .transformation = glm::translate(circ.transformation, {0, 1, 0}),
49 }, fn);
50 break;
51 case CircularPrimitive::CylinderClosed:
52 rasterize(CircularPrimitive{
53 .type = CircularPrimitive::CylinderOpen,
54 .fraction = circ.fraction,
55 .transformation = circ.transformation,
56 }, fn);
57 rasterize(CircularPrimitive{
58 .type = CircularPrimitive::Disc,
59 .fraction = circ.fraction,
60 .transformation = circ.transformation,
61 }, fn);
62 break;
63 case CircularPrimitive::DiscNegative:
64 {
65 unsigned int i = 0;
66 ldraw::circle(circ.fraction.segments, circ.fraction.divisions, [&]
67 (const glm::vec2&, const glm::vec2& p1, const glm::vec2& p2){
68 constexpr glm::vec2 corners[4] = {
69 {+1, +1},
70 {-1, +1},
71 {-1, -1},
72 {+1, -1},
73 };
74 const glm::vec2& corner = corners[i * 4 / circ.fraction.divisions];
75 fn(triangle(xform(p2, 0), xform(p1, 0), xform(corner, 0)));
76 ++i;
77 });
78 }
79 break;
80 case CircularPrimitive::Chord:
81 for (unsigned int i = 1; i < circ.fraction.segments; ++i) {
82 const glm::vec2& p1 = ldraw::rimpoint(circ.fraction.divisions, i);
83 const glm::vec2& p2 = ldraw::rimpoint(circ.fraction.divisions, i + 1);
84 fn(triangle(xform(p2, 0), xform(p1, 0), xform({1, 0}, 0)));
85 }
86 break;
87 }
88 }

mercurial