| 149 | } |
| 150 | |
| 151 | double ConstrainAngleToolHelper::getConstrainedCursorPosMap(const MapCoordF& in_pos, MapCoordF& out_pos) |
| 152 | { |
| 153 | MapCoordF to_cursor = in_pos - center; |
| 154 | double in_angle = -to_cursor.angle(); |
| 155 | if (!active) |
| 156 | { |
| 157 | out_pos = in_pos; |
| 158 | return in_angle; |
| 159 | } |
| 160 | |
| 161 | double lower_angle = in_angle, lower_angle_delta = 999; |
| 162 | double higher_angle = in_angle, higher_angle_delta = -999; |
| 163 | for (auto value : angles) |
| 164 | { |
| 165 | double delta = in_angle - value; |
| 166 | if (delta < -M_PI) |
| 167 | delta = in_angle - (value - 2*M_PI); |
| 168 | else if (delta > M_PI) |
| 169 | delta = (in_angle - 2*M_PI) - value; |
| 170 | |
| 171 | if (delta > 0) |
| 172 | { |
| 173 | if (delta < lower_angle_delta) |
| 174 | { |
| 175 | lower_angle_delta = delta; |
| 176 | lower_angle = value; |
| 177 | } |
| 178 | } |
| 179 | else |
| 180 | { |
| 181 | if (delta > higher_angle_delta) |
| 182 | { |
| 183 | higher_angle_delta = delta; |
| 184 | higher_angle = value; |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | double new_active_angle; |
| 190 | if (lower_angle_delta < -higher_angle_delta) |
| 191 | new_active_angle = lower_angle; |
| 192 | else |
| 193 | new_active_angle = higher_angle; |
| 194 | if (new_active_angle != active_angle) |
| 195 | { |
| 196 | emitActiveAngleChanged(); |
| 197 | active_angle = new_active_angle; |
| 198 | } |
| 199 | |
| 200 | MapCoordF unit_direction = MapCoordF(cos(active_angle), -sin(active_angle)); |
| 201 | to_cursor = MapCoordF::dotProduct(unit_direction, to_cursor) * unit_direction; |
| 202 | out_pos = center + to_cursor; |
| 203 | |
| 204 | return active_angle; |
| 205 | } |
| 206 | |
| 207 | double ConstrainAngleToolHelper::getConstrainedCursorPositions(const MapCoordF& in_pos_map, MapCoordF& out_pos_map, QPointF& out_pos, MapWidget* widget) |
| 208 | { |
no test coverage detected