public void TestBetween1() { Assert.IsFalse(CircularMath.Between(10, 30, 0)); Assert.IsTrue(CircularMath.Between(10, 30, 20)); Assert.IsTrue(CircularMath.Between(10, 30, -340)); Assert.IsFalse(CircularMath.Between(10, 30, 40)); }
public static void OnColorChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { // Force a re-render of the object if a visual-related property changes WheelSelector ctl = (obj as WheelSelector); ctl.InvalidateVisual(); //TODO: Figure out how to handle circular dependencies properly. // Currently I'm using propUpdateFlag to prevent infinite loops here. // Ideally there should be a way to update the local values without calling // this callback again (but still notifying other users) if (!propUpdateFlag) { propUpdateFlag = true; if (args.Property == WheelSelector.ThetaProperty || args.Property == WheelSelector.RadProperty) { ctl.RGBValue = ctl.wheel.ColourMapping(ctl.Rad, CircularMath.Mod(ctl.Theta), 1.0); } if (args.Property == WheelSelector.RGBValueProperty) { var rgb = (RGBColor)args.NewValue; var pt = ctl.wheel.InverseColourMapping(rgb); ctl.SetCurrentValue(ThetaProperty, pt.X); ctl.SetCurrentValue(RadProperty, pt.Y); } propUpdateFlag = false; } }
public void TestBetween2() { Assert.IsTrue(CircularMath.Between(-45, 225, 0)); Assert.IsFalse(CircularMath.Between(-45, 225, 230)); Assert.IsTrue(CircularMath.Between(-45, 225, -5)); Assert.IsFalse(CircularMath.Between(-45, 225, 270)); Assert.IsFalse(CircularMath.Between(-45, 225, -90)); }
public void TestNormMap4() { double start = 315.0; double stop = 225.0; Assert.AreEqual(0.0, CircularMath.NormMap(start, stop, -45.0)); Assert.AreEqual(0.5, CircularMath.NormMap(start, stop, 90.0)); Assert.AreEqual(1.0, CircularMath.NormMap(start, stop, 225.0)); Assert.AreEqual(double.NaN, CircularMath.NormMap(start, stop, 230.0)); Assert.AreEqual(double.NaN, CircularMath.NormMap(start, stop, -55.0)); }
public void TestNormMap2() { double start = 90.0; double stop = 270.0; Assert.AreEqual(0.0, CircularMath.NormMap(start, stop, 90.0)); Assert.AreEqual(0.5, CircularMath.NormMap(start, stop, 180.0)); Assert.AreEqual(1.0, CircularMath.NormMap(start, stop, 270.0)); Assert.AreEqual(double.NaN, CircularMath.NormMap(start, stop, 280.0)); Assert.AreEqual(double.NaN, CircularMath.NormMap(start, stop, 80.0)); }
public void TestNormMap1() { double start = 0.0; double stop = 180.0; Assert.AreEqual(0.0, CircularMath.NormMap(start, stop, 0.0)); Assert.AreEqual(0.5, CircularMath.NormMap(start, stop, 90.0)); Assert.AreEqual(1.0, CircularMath.NormMap(start, stop, 180.0)); Assert.AreEqual(double.NaN, CircularMath.NormMap(start, stop, 190.0)); Assert.AreEqual(double.NaN, CircularMath.NormMap(start, stop, -10.0)); }
private void UpdateArc() { Point center = CalculateCenter(this.ArcOffset); double radius = this.ArcRadius + (this.selector.ActualWidth / 2); arcPathFigure.StartPoint = CircularMath.PointFromAngle(this.ArcStartAngle, radius, center); arcPathSegment.Point = CircularMath.PointFromAngle(this.ArcStopAngle, radius, center); arcPathSegment.Size = new Size(radius, radius); arcPathSegment.IsLargeArc = (Math.Abs(this.ArcStopAngle - this.ArcStartAngle) > 180.0); arcPathSegment.SweepDirection = SweepDirection.Clockwise; }
//Calculations private double CalculateTheta(Point point) { double cx = Bounds.Width / 2; double cy = Bounds.Height / 2; double dx = point.X - cx; double dy = point.Y - cy; double angle = Math.Atan2(dx, dy) / Math.PI * 180.0; // Theta is offset by 180 degrees, so red appears at the top return(CircularMath.Mod(angle - 180.0)); }
private void UpdateSelectorFromPoint(Point point) { // Calculate angle from point (0..360) double angle = CircularMath.AngleFromPoint(point, CalculateCenter(this.ArcOffset)); // Convert to a normalized value between 0.0 and 1.0 double normAngle = CircularMath.NormMap(this.ArcStartAngle, this.ArcStopAngle, angle); // And update the value if (!double.IsNaN(normAngle)) { double value = normAngle * (this.Maximum - this.Minimum) + this.Minimum; this.Value = value; UpdateSelector(); } }
private void UpdateSelector() { double normValue = ((this.Value - this.Minimum) / (this.Maximum - this.Minimum)); if (normValue < 0.0) { normValue = 0.0; } if (normValue > 1.0) { normValue = 1.0; } double angle = normValue * (this.ArcStopAngle - this.ArcStartAngle) + this.ArcStartAngle; double radius = this.ArcRadius + (this.selector.ActualWidth / 2); if (!double.IsNaN(angle)) { Point valuePoint = CircularMath.PointFromAngle(angle, radius, CalculateCenter(this.ArcOffset)); this.selector.Margin = new Thickness(valuePoint.X - this.selector.ActualWidth / 2, valuePoint.Y - this.selector.ActualHeight / 2, 0, 0); (this.selector.RenderTransform as RotateTransform).Angle = angle + 90.0; } }
public void TestMod() { Assert.AreEqual(90, CircularMath.Mod(90)); Assert.AreEqual(90, CircularMath.Mod(450)); Assert.AreEqual(90, CircularMath.Mod(-270)); }