@@ -109,4 +109,107 @@ class RoundedPolygonTest {
109
109
assertEqualish(0.5f , lowerEdge.p3.x)
110
110
assertEqualish(0.0f , lowerEdge.p3.y)
111
111
}
112
- }
112
+
113
+ /*
114
+ * In the following tests, we check how much was cut for the top left (vertex 0) and bottom
115
+ * left corner (vertex 3).
116
+ * In particular, both vertex are competing for space in the left side.
117
+ *
118
+ * Vertex 0 Vertex 1
119
+ * *---------------------*
120
+ * | |
121
+ * *---------------------*
122
+ * Vertex 3 Vertex 2
123
+ */
124
+ private val points = 20
125
+
126
+ @Test
127
+ fun unevenSmoothingTest () {
128
+ // Vertex 3 has the default 0.5 radius, 0 smoothing.
129
+ // Vertex 0 has 0.4 radius, and smoothing varying from 0 to 1.
130
+ repeat(points + 1 ) {
131
+ val smooth = it.toFloat() / points
132
+ doUnevenSmoothTest(
133
+ CornerRounding (0.4f , smooth),
134
+ expectedV0SX = 0.4f * (1 + smooth),
135
+ expectedV0SY = (0.4f * (1 + smooth)).coerceAtMost(0.5f ),
136
+ expectedV3SY = 0.5f ,
137
+ )
138
+ }
139
+ }
140
+
141
+ @Test
142
+ fun unevenSmoothingTest2 () {
143
+ // Vertex 3 has 0.2f radius and 0.2f smoothing, so it takes at most 0.4f
144
+ // Vertex 0 has 0.4f radius and smoothing varies from 0 to 1, when it reaches 0.5 it starts
145
+ // competing with vertex 3 for space.
146
+ repeat(points + 1 ) {
147
+ val smooth = it.toFloat() / points
148
+
149
+ val smoothWantedV0 = 0.4f * smooth
150
+ val smoothWantedV3 = 0.2f
151
+
152
+ // There is 0.4f room for smoothing
153
+ val factor = (0.4f / (smoothWantedV0 + smoothWantedV3)).coerceAtMost(1f )
154
+ doUnevenSmoothTest(
155
+ CornerRounding (0.4f , smooth),
156
+ expectedV0SX = 0.4f * (1 + smooth),
157
+ expectedV0SY = 0.4f + factor * smoothWantedV0,
158
+ expectedV3SY = 0.2f + factor * smoothWantedV3,
159
+ rounding3 = CornerRounding (0.2f , 1f )
160
+ )
161
+ }
162
+ }
163
+
164
+ @Test
165
+ fun unevenSmoothingTest3 () {
166
+ // Vertex 3 has 0.6f radius.
167
+ // Vertex 0 has 0.4f radius and smoothing varies from 0 to 1. There is no room for smoothing
168
+ // on the segment between these vertices, but vertex 0 can still have smoothing on the top
169
+ // side.
170
+ repeat(points + 1 ) {
171
+ val smooth = it.toFloat() / points
172
+
173
+ doUnevenSmoothTest(
174
+ CornerRounding (0.4f , smooth),
175
+ expectedV0SX = 0.4f * (1 + smooth),
176
+ expectedV0SY = 0.4f ,
177
+ expectedV3SY = 0.6f ,
178
+ rounding3 = CornerRounding (0.6f )
179
+ )
180
+ }
181
+ }
182
+
183
+ private fun doUnevenSmoothTest (
184
+ // Corner rounding parameter for vertex 0 (top left)
185
+ rounding0 : CornerRounding ,
186
+ expectedV0SX : Float , // Expected total cut from vertex 0 towards vertex 1
187
+ expectedV0SY : Float , // Expected total cut from vertex 0 towards vertex 3
188
+ expectedV3SY : Float , // Expected total cut from vertex 3 towards vertex 0
189
+ // Corner rounding parameter for vertex 3 (bottom left)
190
+ rounding3 : CornerRounding = CornerRounding (0.5f)
191
+ ) {
192
+ val p0 = PointF (0f , 0f )
193
+ val p1 = PointF (5f , 0f )
194
+ val p2 = PointF (5f , 1f )
195
+ val p3 = PointF (0f , 1f )
196
+
197
+ val pvRounding = listOf (
198
+ rounding0,
199
+ CornerRounding .Unrounded ,
200
+ CornerRounding .Unrounded ,
201
+ rounding3,
202
+ )
203
+ val polygon = RoundedPolygon (
204
+ vertices = listOf (p0, p1, p2, p3),
205
+ perVertexRounding = pvRounding
206
+ )
207
+ val (e01, _, _, e30) = polygon.features.filterIsInstance<RoundedPolygon .Edge >()
208
+ val msg = " r0 = ${show(rounding0)} , r3 = ${show(rounding3)} "
209
+ assertEqualish(expectedV0SX, e01.cubics.first().p0.x, msg)
210
+ assertEqualish(expectedV0SY, e30.cubics.first().p3.y, msg)
211
+ assertEqualish(expectedV3SY, 1f - e30.cubics.first().p0.y, msg)
212
+ }
213
+
214
+ private fun show (cr : CornerRounding ) = " (r=${cr.radius} , s=${cr.smoothing} )"
215
+ }
0 commit comments