diff --git a/lib/ui/geometry.dart b/lib/ui/geometry.dart index 2f7b03d67cde6..5249f1c03c1b7 100644 --- a/lib/ui/geometry.dart +++ b/lib/ui/geometry.dart @@ -142,6 +142,35 @@ class Offset extends OffsetBase { /// This is cheaper than computing the [distance] itself. double get distanceSquared => _dx * _dx + _dy * _dy; + /// The angle of this offset as radians clockwise from the positive x-axis, in + /// the range -[pi] to [pi], assuming positive values of the x-axis go to the + /// left and positive values of the y-axis go down. + /// + /// Zero means that [dy] is zero and [dx] is zero or positive. + /// + /// Values from zero to [pi]/2 indicate positive values of [dx] and [dy], the + /// bottom-right quadrant. + /// + /// Values from [pi]/2 to [pi] indicate negative values of [dx] and positive + /// values of [dy], the bottom-left quadrant. + /// + /// Values from zero to -[pi]/2 indicate positive values of [dx] and negative + /// values of [dy], the top-right quadrant. + /// + /// Values from -[pi]/2 to -[pi] indicate negative values of [dx] and [dy], + /// the top-left quadrant. + /// + /// When [dy] is zero and [dx] is negative, the [direction] is [pi]. + /// + /// When [dx] is zero, [direction] is [pi]/2 if [dy] is positive and -[pi]/2 + /// if [dy] is negative. + /// + /// See also: + /// + /// * [distance], to compute the magnitude of the vector. + /// * [Canvas.rotate], which uses the same convention for its angle. + double get direction => math.atan2(dy, dx); + /// An offset with zero magnitude. /// /// This can be used to represent the origin of a coordinate space. diff --git a/testing/dart/geometry_test.dart b/testing/dart/geometry_test.dart new file mode 100644 index 0000000000000..fc3ce17434233 --- /dev/null +++ b/testing/dart/geometry_test.dart @@ -0,0 +1,22 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:ui'; +import 'dart:math' show pi; + +import 'package:test/test.dart'; + +void main() { + test('Offset.direction', () { + expect(const Offset(0.0, 0.0).direction, 0.0); + expect(const Offset(0.0, 1.0).direction, pi / 2.0); + expect(const Offset(0.0, -1.0).direction, -pi / 2.0); + expect(const Offset(1.0, 0.0).direction, 0.0); + expect(const Offset(1.0, 1.0).direction, pi / 4.0); + expect(const Offset(1.0, -1.0).direction, -pi / 4.0); + expect(const Offset(-1.0, 0.0).direction, pi); + expect(const Offset(-1.0, 1.0).direction, pi * 3.0 / 4.0); + expect(const Offset(-1.0, -1.0).direction, -pi * 3.0 / 4.0); + }); +}