From c5e17020c7ebe5b7586438328d7afdfb886f6840 Mon Sep 17 00:00:00 2001 From: Jon Mease Date: Mon, 8 Jan 2024 18:37:37 -0500 Subject: [PATCH] Fix rotation of symbols with stroke --- .../symbol/wedge_stroke_angle.dims.json | 6 + .../symbol/wedge_stroke_angle.png | Bin 0 -> 12602 bytes .../symbol/wedge_stroke_angle.sg.json | 127 ++++++++++++++++++ .../symbol/wedge_stroke_angle.vg.json | 40 ++++++ sg2d-wgpu/src/marks/polygon_symbol.wgsl | 3 +- sg2d-wgpu/tests/test_image_baselines.rs | 1 + 6 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.dims.json create mode 100644 sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.png create mode 100644 sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.sg.json create mode 100644 sg2d-vega-test-data/vega-specs/symbol/wedge_stroke_angle.vg.json diff --git a/sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.dims.json b/sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.dims.json new file mode 100644 index 0000000..50fd0bc --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.dims.json @@ -0,0 +1,6 @@ +{ + "width": 500, + "height": 100, + "origin_x": 0, + "origin_y": 0 +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.png b/sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.png new file mode 100644 index 0000000000000000000000000000000000000000..ee809922c063d43050ca2463b6aa47c807781217 GIT binary patch literal 12602 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 F{};w-xtIU| literal 0 HcmV?d00001 diff --git a/sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.sg.json b/sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.sg.json new file mode 100644 index 0000000..7d7e7db --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/symbol/wedge_stroke_angle.sg.json @@ -0,0 +1,127 @@ +{ + "marktype": "group", + "name": "root", + "role": "frame", + "interactive": true, + "clip": false, + "items": [ + { + "items": [ + { + "marktype": "symbol", + "role": "mark", + "interactive": true, + "clip": false, + "items": [ + { + "x": 30, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 600, + "shape": "wedge", + "angle": 0 + }, + { + "x": 60, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 1200, + "shape": "wedge", + "angle": 30 + }, + { + "x": 90, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 1800, + "shape": "wedge", + "angle": 90 + }, + { + "x": 150, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 2200, + "shape": "wedge", + "angle": 120 + }, + { + "x": 200, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 2800, + "shape": "wedge", + "angle": 180 + }, + { + "x": 250, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 3000, + "shape": "wedge", + "angle": 240 + }, + { + "x": 310, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 1600, + "shape": "wedge", + "angle": 270 + }, + { + "x": 360, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 2400, + "shape": "wedge", + "angle": 300 + }, + { + "x": 400, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 3000, + "shape": "wedge", + "angle": 330 + }, + { + "x": 450, + "y": 40, + "fill": "red", + "stroke": "black", + "strokeWidth": 3, + "size": 3600, + "shape": "wedge", + "angle": 360 + } + ], + "zindex": 0 + } + ], + "x": 0, + "y": 0, + "width": 500, + "height": 100 + } + ], + "zindex": 0 +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-specs/symbol/wedge_stroke_angle.vg.json b/sg2d-vega-test-data/vega-specs/symbol/wedge_stroke_angle.vg.json new file mode 100644 index 0000000..90e7161 --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/symbol/wedge_stroke_angle.vg.json @@ -0,0 +1,40 @@ +{ + "width": 500, + "height": 100, + "background": "white", + "data": [ + { + "name": "data_1", + "values": [ + {"x": 30, "angle": 0, "size": 600}, + {"x": 60, "angle": 30, "size": 1200}, + {"x": 90, "angle": 90, "size": 1800}, + {"x": 150, "angle": 120, "size": 2200}, + {"x": 200, "angle": 180, "size": 2800}, + {"x": 250, "angle": 240, "size": 3000}, + {"x": 310, "angle": 270, "size": 1600}, + {"x": 360, "angle": 300, "size": 2400}, + {"x": 400, "angle": 330, "size": 3000}, + {"x": 450, "angle": 360, "size": 3600} + ] + } + ], + "marks": [ + { + "type": "symbol", + "from": {"data": "data_1"}, + "encode": { + "update": { + "x": {"field": "x"}, + "y": {"value": 40}, + "shape": {"value": "wedge"}, + "fill": {"value": "red"}, + "stroke": {"value": "black"}, + "strokeWidth": {"value": 3}, + "size": {"field": "size"}, + "angle": {"field": "angle"} + } + } + } + ] +} \ No newline at end of file diff --git a/sg2d-wgpu/src/marks/polygon_symbol.wgsl b/sg2d-wgpu/src/marks/polygon_symbol.wgsl index 7c41414..22fcd52 100644 --- a/sg2d-wgpu/src/marks/polygon_symbol.wgsl +++ b/sg2d-wgpu/src/marks/polygon_symbol.wgsl @@ -63,8 +63,9 @@ fn vs_main( // The factor of 2.0 here is because the normal vector that lyon // returns has length such that moving all stroke vertices by the length // of the "normal" vector will increase the line width by 2. + let normal = rot * model.normal; var diff = scaled_stroke_width - instance.stroke_width; - let adjusted_pos = pos - diff * model.normal / 2.0; + let adjusted_pos = pos - diff * normal / 2.0; let normalized_pos = 2.0 * adjusted_pos / chart_uniforms.size - 1.0; out.clip_position = vec4(normalized_pos, 0.0, 1.0); diff --git a/sg2d-wgpu/tests/test_image_baselines.rs b/sg2d-wgpu/tests/test_image_baselines.rs index 113f53b..7f581e1 100644 --- a/sg2d-wgpu/tests/test_image_baselines.rs +++ b/sg2d-wgpu/tests/test_image_baselines.rs @@ -36,6 +36,7 @@ mod test_image_baselines { case("symbol", "scatter_transparent_stroke_star", 0.005), case("symbol", "wind_vector", 0.0015), case("symbol", "wedge_angle", 0.001), + case("symbol", "wedge_stroke_angle", 0.001), case("rule", "wide_rule_axes", 0.0001), case("text", "bar_axis_labels", 0.01) )]