예제 #1
0
        public virtual object Clone()
        {
            PathToolSegment newSeg = new PathToolSegment();

            CopyTo(newSeg);
            return(newSeg);
        }
예제 #2
0
        public virtual void CopyTo(PathToolSegment other)
        {
            StartAnchor.CopyDataValues(other.StartAnchor);
            EndAnchor.CopyDataValues(other.EndAnchor);

            other.Name = Name;
        }
예제 #3
0
        public override bool IsAlertConditionTrue(AlertConditionItem conditionItem, Condition condition, ChartAlertValue[] values, ChartControl chartControl, ChartScale chartScale)
        {
            PathToolSegment segAnchors = conditionItem.Tag as PathToolSegment;

            if (segAnchors == null)
            {
                return(false);
            }

            ChartPanel chartPanel     = chartControl.ChartPanels[PanelIndex];
            Point      lineStartPoint = segAnchors.StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      lineEndPoint   = segAnchors.EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
            double     minLineX       = double.MaxValue;
            double     maxLineX       = double.MinValue;

            foreach (Point point in new[] { lineStartPoint, lineEndPoint })
            {
                minLineX = Math.Min(minLineX, point.X);
                maxLineX = Math.Max(maxLineX, point.X);
            }

            // first thing, if our smallest x is greater than most recent bar, we have nothing to do yet.
            // do not try to check Y because lines could cross through stuff
            double firstBarX = values[0].ValueType == ChartAlertValueType.StaticValue ? minLineX : chartControl.GetXByTime(values[0].Time);
            double firstBarY = chartScale.GetYByValue(values[0].Value);

            // dont have to take extension into account as its already handled in min/max line x

            // bars completely passed our line
            if (maxLineX < firstBarX)
            {
                return(false);
            }

            // bars not yet to our line
            if (minLineX > firstBarX)
            {
                return(false);
            }

            // NOTE: normalize line points so the leftmost is passed first. Otherwise, our vector
            // math could end up having the line normal vector being backwards if user drew it backwards.
            // but we dont care the order of anchors, we want 'up' to mean 'up'!
            Point leftPoint  = lineStartPoint.X < lineEndPoint.X ? lineStartPoint : lineEndPoint;
            Point rightPoint = lineEndPoint.X > lineStartPoint.X ? lineEndPoint : lineStartPoint;
            Point barPoint   = new Point(firstBarX, firstBarY);

            // NOTE: 'left / right' is relative to if line was vertical. it can end up backwards too
            MathHelper.PointLineLocation pointLocation = MathHelper.GetPointLineLocation(leftPoint, rightPoint, barPoint);

            // for vertical things, think of a vertical line rotated 90 degrees to lay flat, where it's normal vector is 'up'
            switch (condition)
            {
            case Condition.Greater:                 return(pointLocation == MathHelper.PointLineLocation.LeftOrAbove);

            case Condition.GreaterEqual:    return(pointLocation == MathHelper.PointLineLocation.LeftOrAbove || pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.Less:                    return(pointLocation == MathHelper.PointLineLocation.RightOrBelow);

            case Condition.LessEqual:               return(pointLocation == MathHelper.PointLineLocation.RightOrBelow || pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.Equals:                  return(pointLocation == MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.NotEqual:                return(pointLocation != MathHelper.PointLineLocation.DirectlyOnLine);

            case Condition.CrossAbove:
            case Condition.CrossBelow:
                Predicate <ChartAlertValue> predicate = v =>
                {
                    double barX         = chartControl.GetXByTime(v.Time);
                    double barY         = chartScale.GetYByValue(v.Value);
                    Point  stepBarPoint = new Point(barX, barY);
                    MathHelper.PointLineLocation ptLocation = MathHelper.GetPointLineLocation(leftPoint, rightPoint, stepBarPoint);

                    if (condition == Condition.CrossAbove)
                    {
                        return(ptLocation == MathHelper.PointLineLocation.LeftOrAbove);
                    }
                    return(ptLocation == MathHelper.PointLineLocation.RightOrBelow);
                };

                return(MathHelper.DidPredicateCross(values, predicate));
            }

            return(false);
        }