internal void DrawLine(Point startPoint, Point endPoint) { var p1 = startPoint; var p2 = endPoint; var distance = (p1 - p2).Length; var angle = CalculateAngle(p1, p2); var waveLength = WaveLength; var waveHeight = WaveHeight; var howManyWaves = distance / waveLength; //var waveInterval = distance / howManyWaves; var waveInterval = waveLength; var maxBcpLength = Math.Sqrt(waveInterval / 4.0 * (waveInterval / 4.0) + waveHeight / 2.0 * (waveHeight / 2.0)); var curveSquaring = CurveSquaring; var bcpLength = maxBcpLength * curveSquaring; var bcpInclination = CalculateAngle(new Point(0, 0), new Point(waveInterval / 4.0, waveHeight / 2.0)); var wigglePoints = new List <(Point bcpOut, Point bcpIn, Point anchor)>(); //添加起始点 wigglePoints.Add((new Point(), new Point(), p1)); //添加一系列数据集 var prevFlexPt = p1; var polarity = 1; for (var waveIndex = 0; waveIndex < howManyWaves * 2; waveIndex++) { var bcpOutAngle = angle + bcpInclination * polarity; var bcpOut = new Point(prevFlexPt.X + Math.Cos(bcpOutAngle) * bcpLength, prevFlexPt.Y + Math.Sin(bcpOutAngle) * bcpLength); var flexPt = new Point(prevFlexPt.X + Math.Cos(angle) * waveInterval / 2.0, prevFlexPt.Y + Math.Sin(angle) * waveInterval / 2.0); var bcpInAngle = angle + (Math.PI - bcpInclination) * polarity; var bcpIn = new Point(flexPt.X + Math.Cos(bcpInAngle) * bcpLength, flexPt.Y + Math.Sin(bcpInAngle) * bcpLength); wigglePoints.Add((bcpOut, bcpIn, flexPt)); polarity *= -1; prevFlexPt = flexPt; } //纠正尾头过长/过短问题 if (wigglePoints.Count > 1) { var wigglePoint = wigglePoints[wigglePoints.Count - 1]; if (wigglePoint.bcpOut.X > endPoint.X) { wigglePoints.Remove(wigglePoint); wigglePoints.Add((p2, p2, p2)); } else if (wigglePoint.bcpIn.X > endPoint.X) { wigglePoints.Remove(wigglePoint); wigglePoints.Add((wigglePoint.bcpOut, p2, p2)); } else if (wigglePoint.anchor.X > endPoint.X) { wigglePoints.Remove(wigglePoint); wigglePoints.Add((wigglePoint.bcpOut, wigglePoint.bcpIn, p2)); } } var streamGeometry = new StreamGeometry(); using (var streamGeometryContext = streamGeometry.Open()) { streamGeometryContext.BeginFigure(wigglePoints[0].anchor, true, false); for (var i = 1; i < wigglePoints.Count; i += 1) { var(bcpOut, bcpIn, anchor) = wigglePoints[i]; streamGeometryContext.BezierTo(bcpOut, bcpIn, anchor, true, false); } } var visual = new DrawingVisual(); using (var context = visual.RenderOpen()) { context.DrawGeometry(FillBrush, StrokePen, streamGeometry); } _visualShape.Add(visual); }
private void RenderPolygon(DrawingContext drawingContext) { var fillBrush = Brushes.LawnGreen; var borderPen = new Pen(Brushes.DarkGreen, 1.0); if (WaveformDisplayMode == WaveformDisplayMode.Linear) { sampleTransformerFunc = (x => x); } else if (WaveformDisplayMode == WaveformDisplayMode.Logarithmic) { sampleTransformerFunc = (x => Math.Sign(x) * LoudnessHelper.VolumeFromLoudness(Math.Abs(x))); } else { throw new InvalidOperationException("display mode not supported: " + WaveformDisplayMode); } var maximums = Waveform.Maximums; var minimums = Waveform.Minimums; if (maximums.Length == 0) { return; } // px/sample = px/sec * sec/sample double xScale = TimeScale * Waveform.TimePerSample; double offsetPx = Waveform.TimeOffset * TimeScale; double rightmostPx = offsetPx + maximums.Length * xScale; StreamGeometry geometry = new StreamGeometry(); using (var ctx = geometry.Open()) { ctx.BeginFigure(new Point(offsetPx, SampleToYPosition(maximums[0])), isFilled: true, isClosed: true); for (int i = 1; i < maximums.Length; i++) { ctx.LineTo(new Point(offsetPx + i * xScale, SampleToYPosition(maximums[i])), true, false); } ctx.LineTo(new Point(rightmostPx, SampleToYPosition(maximums[maximums.Length - 1])), true, false); ctx.LineTo(new Point(rightmostPx, SampleToYPosition(minimums[minimums.Length - 1])), true, false); for (int i = minimums.Length - 1; i >= 0; i--) { ctx.LineTo(new Point(offsetPx + i * xScale, SampleToYPosition(minimums[i])), true, false); } } geometry.Freeze(); drawingContext.DrawGeometry(fillBrush, borderPen, geometry); // Alternative rendering method that draws rectangles/lines directly onto the drawingContext. //for (int i=0; i<maximums.Length; i++) //{ // double y = SampleToYPosition(maximums[i]); // double h = SampleToYPosition(minimums[i]) - y; // if (h > halfHeight * 0.1 || i == 0) // { // drawingContext.DrawRectangle(fillBrush, null, new Rect( // offsetPx + i * xScale, y, // xScale, h)); // } else // { // double prevMid = (SampleToYPosition(maximums[i - 1]) + SampleToYPosition(minimums[i - 1])) / 2; // drawingContext.DrawLine(new Pen(fillBrush, 3), // new Point(offsetPx + (i-1) * xScale, prevMid), // new Point(offsetPx + i * xScale, y + h/2)); // } //} }
private static void OnHeaderSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { TonyTabItem tonyTabItem = d as TonyTabItem; TonyTabControl tonyTabControl = tonyTabItem.Parent as TonyTabControl; if (tonyTabControl == null) { return; } if (tonyTabItem.mainGrid == null) { return; } if (tonyTabItem.lbHeader == null) { return; } //处理leftMargin和HeaderHeight List <TonyTabItem> items = new List <TonyTabItem>(); foreach (var item in tonyTabControl.Items) { items.Add(item as TonyTabItem); } //找出最大的HeaderHeight double headerHeightMax = (from i in items select i.HeaderHeight).Max(); //都设置为最大的headerHeightMax items.ForEach(x => x.HeaderHeight = headerHeightMax); //处理leftMargin:TonyTabItem中的Leftmargin是Header和左边的距离,现在改为Header与Header的距离 double leftMargin = 0; foreach (TonyTabItem item in items) { leftMargin += item.HeaderLeftMargin; //item.HeaderLeftMarginEx = leftMargin; if (item == tonyTabItem) { break; } leftMargin += item.HeaderWidth; } //获取LeftMargin:Header距离最左边的距离 tonyTabItem.HeaderLeftMarginEx = leftMargin; //设置Header的Margin tonyTabItem.lbHeader.Margin = new Thickness(leftMargin, 0, 0, 0); //处理剪切 double left = tonyTabItem.HeaderLeftMarginEx; double h = tonyTabItem.HeaderHeight; double w = tonyTabItem.HeaderWidth; double ah = tonyTabControl.ActualHeight; double aw = tonyTabControl.ActualWidth; //Header 有4个点,ContentPresenter有各点,按点裁剪 Point p1 = new Point(left, 0); Point p2 = new Point(left + w, 0); Point p3 = new Point(left + w, h); Point p4 = new Point(aw, h); Point p5 = new Point(aw, ah); Point p6 = new Point(0, ah); Point p7 = new Point(0, h); Point p8 = new Point(left, h); StreamGeometry geometry = new StreamGeometry(); using (StreamGeometryContext ctx = geometry.Open()) { ctx.BeginFigure(p1, true, true); ctx.LineTo(p2, true, true); ctx.LineTo(p3, true, true); ctx.LineTo(p4, true, true); ctx.LineTo(p5, true, true); ctx.LineTo(p6, true, true); ctx.LineTo(p7, true, true); ctx.LineTo(p8, true, true); } tonyTabItem.mainGrid.Clip = geometry;//按照Header进行裁剪 }