From b377bbac5983a044b80b43adcb3d871eebee4d25 Mon Sep 17 00:00:00 2001 From: plex <344565768@qq.com> Date: Wed, 18 Jul 2018 22:43:45 +0800 Subject: [PATCH 1/2] fix: change the start angle of the regular polygon to match the sketch --- src/ol/interaction/Draw.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ol/interaction/Draw.js b/src/ol/interaction/Draw.js index 52796f5e96..81f7f1fb91 100644 --- a/src/ol/interaction/Draw.js +++ b/src/ol/interaction/Draw.js @@ -956,8 +956,19 @@ export function createRegularPolygon(opt_sides, opt_angle) { squaredCoordinateDistance(center, end)); const geometry = opt_geometry ? /** @type {module:ol/geom/Polygon} */ (opt_geometry) : fromCircle(new Circle(center), opt_sides); - const angle = opt_angle ? opt_angle : + let angle = opt_angle ? opt_angle : Math.atan((end[1] - center[1]) / (end[0] - center[0])); + let _angle = 180 * angle / Math.PI; + if (end[0] - center[0] >= 0 && end[1] - center[1] <= 0) { + _angle = _angle + 360; + } else if (end[0] - center[0] >= 0 && end[1] - center[1] >= 0) { + _angle = _angle; + } else if (end[0] - center[0] <= 0 && end[1] - center[1] >= 0) { + _angle = _angle + 180; + } else if (end[0] - center[0] <= 0 && end[1] - center[1] <= 0) { + _angle = _angle + 180; + } + angle = _angle * Math.PI / 180; makeRegular(geometry, center, radius, angle); return geometry; }; From 45cf296ed4485e43917c4772a63e1747516edf91 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Sat, 21 Jul 2018 09:44:52 +0200 Subject: [PATCH 2/2] Simplify calculation and add tests --- src/ol/interaction/Draw.js | 17 +++----- test/spec/ol/interaction/draw.test.js | 56 +++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/ol/interaction/Draw.js b/src/ol/interaction/Draw.js index 81f7f1fb91..f0412bbd2f 100644 --- a/src/ol/interaction/Draw.js +++ b/src/ol/interaction/Draw.js @@ -956,19 +956,12 @@ export function createRegularPolygon(opt_sides, opt_angle) { squaredCoordinateDistance(center, end)); const geometry = opt_geometry ? /** @type {module:ol/geom/Polygon} */ (opt_geometry) : fromCircle(new Circle(center), opt_sides); - let angle = opt_angle ? opt_angle : - Math.atan((end[1] - center[1]) / (end[0] - center[0])); - let _angle = 180 * angle / Math.PI; - if (end[0] - center[0] >= 0 && end[1] - center[1] <= 0) { - _angle = _angle + 360; - } else if (end[0] - center[0] >= 0 && end[1] - center[1] >= 0) { - _angle = _angle; - } else if (end[0] - center[0] <= 0 && end[1] - center[1] >= 0) { - _angle = _angle + 180; - } else if (end[0] - center[0] <= 0 && end[1] - center[1] <= 0) { - _angle = _angle + 180; + let angle = opt_angle; + if (!opt_angle) { + const x = end[0] - center[0]; + const y = end[1] - center[1]; + angle = Math.atan(y / x) - (x < 0 ? Math.PI : 0); } - angle = _angle * Math.PI / 180; makeRegular(geometry, center, radius, angle); return geometry; }; diff --git a/test/spec/ol/interaction/draw.test.js b/test/spec/ol/interaction/draw.test.js index b2497c166f..f0b95de23e 100644 --- a/test/spec/ol/interaction/draw.test.js +++ b/test/spec/ol/interaction/draw.test.js @@ -62,6 +62,7 @@ describe('ol.interaction.Draw', function() { * @param {number} x Horizontal offset from map center. * @param {number} y Vertical offset from map center. * @param {boolean=} opt_shiftKey Shift key is pressed. + * @return {module:ol/MapBrowserPointerEvent} The simulated event. */ function simulateEvent(type, x, y, opt_shiftKey) { const viewport = map.getViewport(); @@ -72,8 +73,12 @@ describe('ol.interaction.Draw', function() { clientX: position.left + x + width / 2, clientY: position.top + y + height / 2, shiftKey: shiftKey + }, { + pointerType: 'mouse' }); - map.handleMapBrowserEvent(new MapBrowserPointerEvent(type, map, event)); + const simulatedEvent = new MapBrowserPointerEvent(type, map, event); + map.handleMapBrowserEvent(simulatedEvent); + return simulatedEvent; } describe('constructor', function() { @@ -1059,8 +1064,7 @@ describe('ol.interaction.Draw', function() { const draw = new Draw({ source: source, type: 'Circle', - geometryFunction: - createRegularPolygon(4, Math.PI / 4) + geometryFunction: createRegularPolygon(4, Math.PI / 4) }); map.addInteraction(draw); @@ -1082,6 +1086,52 @@ describe('ol.interaction.Draw', function() { expect(coordinates[0][0][0]).to.roughlyEqual(20, 1e-9); expect(coordinates[0][0][1]).to.roughlyEqual(20, 1e-9); }); + + it('sketch start point always matches the mouse point', function() { + const draw = new Draw({ + source: source, + type: 'Circle', + geometryFunction: createRegularPolygon(3) + }); + map.addInteraction(draw); + + // regular polygon center point + simulateEvent('pointermove', 60, 60); + simulateEvent('pointerdown', 60, 60); + simulateEvent('pointerup', 60, 60); + + // move to first quadrant + simulateEvent('pointermove', 79, 80); + let event = simulateEvent('pointermove', 80, 80); + let coordinate = event.coordinate; + const firstQuadrantCoordinate = draw.sketchFeature_.getGeometry().getFirstCoordinate(); + expect(firstQuadrantCoordinate[0]).to.roughlyEqual(coordinate[0], 1e-9); + expect(firstQuadrantCoordinate[1]).to.roughlyEqual(coordinate[1], 1e-9); + + // move to second quadrant + simulateEvent('pointermove', 41, 80); + event = simulateEvent('pointermove', 40, 80); + coordinate = event.coordinate; + const secondQuadrantCoordinate = draw.sketchFeature_.getGeometry().getFirstCoordinate(); + expect(secondQuadrantCoordinate[0]).to.roughlyEqual(coordinate[0], 1e-9); + expect(secondQuadrantCoordinate[1]).to.roughlyEqual(coordinate[1], 1e-9); + + // move to third quadrant + simulateEvent('pointermove', 40, 41); + event = simulateEvent('pointermove', 40, 40); + coordinate = event.coordinate; + const thirdQuadrantCoordinate = draw.sketchFeature_.getGeometry().getFirstCoordinate(); + expect(thirdQuadrantCoordinate[0]).to.roughlyEqual(coordinate[0], 1e-9); + expect(thirdQuadrantCoordinate[1]).to.roughlyEqual(coordinate[1], 1e-9); + + // move to fourth quadrant + simulateEvent('pointermove', 79, 40); + event = simulateEvent('pointermove', 80, 40); + coordinate = event.coordinate; + const fourthQuadrantCoordinate = draw.sketchFeature_.getGeometry().getFirstCoordinate(); + expect(fourthQuadrantCoordinate[0]).to.roughlyEqual(coordinate[0], 1e-9); + expect(fourthQuadrantCoordinate[1]).to.roughlyEqual(coordinate[1], 1e-9); + }); }); describe('createBox', function() {