//计算线段对应比例点 private void CalcButton_Click(object sender, EventArgs e) { try { float Ratio = (float)(PolyLineRatioScrollBar.Value / 100.0); double ScaleRatio = Convert.ToDouble(RatioTextBox.Text); if (Ratio < 0 || Ratio > 1) { throw new Exception("所求线段比例非法!"); } else { PlotPoint Target = new PlotPoint(); //为所求点新建对象 Target = Algorithm.GetPointPos(Line.Points, Ratio); //计算所求点位置 ClearAndDraw(); PolyLineDrawing.DrawPoints(Target, PlotPointPictureBox, Algorithm.InverseColor(PointColorPictureBox.BackColor), PointWidthTrackBar.Value); PolyLineDrawing.DrawFonts(Target, "P", PlotPointPictureBox, FontColorPictureBox.BackColor, FontStyleDisplayLabel.Font, PointWidthTrackBar.Value); PlotPointPictureBox.Invalidate(); //计算并输出实际坐标系点位 PlotPoint Corrected = Algorithm.GetActualPos(PlotPointPictureBox, Target); ResultLabel.Text = "点位:(" + (Corrected.X * ScaleRatio / PlotPointPictureBox.Width).ToString("0.0000") + ", " + (Corrected.Y * ScaleRatio / PlotPointPictureBox.Width).ToString("0.0000") + ") (m)"; IsCalculated = true; } } catch (Exception err) { MessageBoxes.Error(err.Message); } }
//点绘制方法 internal static void DrawPoints(PlotPoint Points, PictureBox TargetPictureBox, Color PointColor, int PointWidth) { Graphics g = Graphics.FromImage(TargetPictureBox.BackgroundImage); g.SmoothingMode = SmoothingMode.AntiAlias; Brush PointBrush = new SolidBrush(PointColor); g.FillEllipse(PointBrush, Points.X - PointWidth / 2, Points.Y - PointWidth / 2, PointWidth, PointWidth); }
internal static void DrawLines(PlotPoint Point1, PlotPoint Point2, PictureBox TargetPictureBox, Color LineColor, int LineWidth) { Graphics g = Graphics.FromImage(TargetPictureBox.BackgroundImage); g.SmoothingMode = SmoothingMode.AntiAlias; Pen DrawLines = new Pen(LineColor, LineWidth); g.DrawLine(DrawLines, Point1.X, Point1.Y, Point2.X, Point2.Y); }
//预览线绘制方法 internal static void DrawPreviewLine(PlotPoint StartPoint, PlotPoint EndPoint, PictureBox TargetPictureBox, Color LineColor, int LineWidth) { Graphics g = Graphics.FromImage(TargetPictureBox.BackgroundImage); g.SmoothingMode = SmoothingMode.AntiAlias; Pen DrawLines = new Pen(LineColor, LineWidth) { //预览线虚线样式 DashStyle = DashStyle.Custom, DashPattern = new float[] { 2, 2 } }; g.DrawLine(DrawLines, StartPoint.X, StartPoint.Y, EndPoint.X, EndPoint.Y); }
//文字绘制方法 internal static void DrawFonts(PlotPoint Points, string No, PictureBox TargetPictureBox, Color FontColor, Font FontStyle, int PointWidth) { Graphics g = Graphics.FromImage(TargetPictureBox.BackgroundImage); g.SmoothingMode = SmoothingMode.AntiAlias; Font PointStyle = FontStyle; SolidBrush PointBrush = new SolidBrush(FontColor); PointF FontPos = new PointF { X = Convert.ToSingle(Points.X - FontStyle.Size / 2 + FontStyle.Size * -Math.Cos(Math.Atan2(Points.Y - TargetPictureBox.Height / 2, Points.X - TargetPictureBox.Width / 2))), Y = Convert.ToSingle(Points.Y - FontStyle.Size / 2 + FontStyle.Size * -Math.Sin(Math.Atan2(Points.Y - TargetPictureBox.Height / 2, Points.X - TargetPictureBox.Width / 2))) }; g.DrawString(No, PointStyle, PointBrush, FontPos.X, FontPos.Y); }
//获取所求比例点坐标 internal static PlotPoint GetPointPos(List <PlotPoint> Points, float Proportion) { if (Points.Count <= 1) { throw new Exception("点位过少"); } if (Proportion == 0) { float xx = Points[0].X; float yy = Points[0].Y; PlotPoint PointPos = new PlotPoint { X = xx, Y = yy }; return(PointPos); } else { double TargetLength = GetPolyLineLength(Points) * Proportion; //获取目标长度 int i = 0; double CurrentLength = 0.0; //获取超过指定比例长度的第一个点 while (CurrentLength < TargetLength) { CurrentLength += GetSingleLineLength(Points[i], Points[i + 1]); i++; } //获取超过指定比例长度的前一个点 int j = i - 1; double PreLength = CurrentLength - GetSingleLineLength(Points[j], Points[i]); //获取至前一点的长度 double RemainLength = TargetLength - PreLength; //获取在目标线段上的剩余距离 double CurrentLineLength = GetSingleLineLength(Points[j], Points[i]); //获取目标点所在线段长度 float Pro = (float)(RemainLength / CurrentLineLength); //计算目标点在线段上的比例 PlotPoint PointPos = new PlotPoint { X = Points[j].X + (Points[i].X - Points[j].X) * Pro, Y = Points[j].Y + (Points[i].Y - Points[j].Y) * Pro }; return(PointPos); } }
//预览或编辑 private void PreviewOrEdit(object sender, MouseEventArgs e) { try { //预览 if (IsDrawing && IsPreviewing) { PlotPoint Preview = new PlotPoint { X = e.X, Y = e.Y }; ClearAndDraw(); if (Line.Points.Count > 0) { if (PolyLineCalcGroupBox.Visible) { PolyLineLengthLabel.Text = "折线长度:" + (((Algorithm.GetPolyLineLength(Line.Points) + Algorithm.GetSingleLineLength(Line.Points[Line.Points.Count - 1], Preview)) / (PlotPointPictureBox.Width)) * Convert.ToDouble(RatioTextBox.Text)).ToString("0.0000") + " (m)"; } if (IsPolygonCheckBox.Checked) { if (Line.Points.Count > 1) { PolyLineDrawing.DrawPolygon(Line.Points, PlotPointPictureBox, PolygonColorPictureBox.BackColor, PolygonTransparencyTrackBar.Value * 255 / (PolygonTransparencyTrackBar.Maximum - PolygonTransparencyTrackBar.Minimum), Preview); List <PlotPoint> PreviewArea = new List <PlotPoint>(); for (int i = 0; i < Line.Points.Count(); i++) { PreviewArea.Add(Line.Points[i]); } PreviewArea.Add(Preview); PolygonAreaLabel.Text = "多边形面积:" + (Algorithm.GetPolygonArea(PreviewArea, PlotPointPictureBox, Convert.ToSingle(RatioTextBox.Text))).ToString("0.0000") + "(m ^ 2)"; } PolyLineDrawing.DrawPreviewLine(Line.Points[0], Preview, PlotPointPictureBox, Algorithm.InverseColor(LineColorPictureBox.BackColor), LineWidthTrackBar.Value); } PolyLineDrawing.DrawPreviewLine(Line.Points[Line.Points.Count - 1], Preview, PlotPointPictureBox, Algorithm.InverseColor(LineColorPictureBox.BackColor), LineWidthTrackBar.Value); } PolyLineDrawing.DrawPoints(Preview, PlotPointPictureBox, Algorithm.InverseColor(PointColorPictureBox.BackColor), PointWidthTrackBar.Value); PolyLineDrawing.DrawFonts(Preview, Convert.ToString(Line.Points.Count + 1), PlotPointPictureBox, FontColorPictureBox.BackColor, FontStyleDisplayLabel.Font, PointWidthTrackBar.Value); PlotPointPictureBox.Invalidate(); } //编辑 if (!IsDrawing && IsEditing && !IsPointMoving && Line.Points.Count != 0) { PlotPointPictureBox.Cursor = Cursors.Arrow; List <double> Dis = new List <double>(); PlotPoint EditPos = new PlotPoint { X = e.X, Y = e.Y }; foreach (PlotPoint Point in Line.Points) { Dis.Add(Algorithm.GetSingleLineLength(EditPos, Point)); } //找最小距离点 double MinDistance = Dis[0]; int MinDistanceIndex = 0; for (int i = 0; i < Dis.Count; i++) { if (Dis[i] < MinDistance) { MinDistance = Dis[i]; MinDistanceIndex = i; } } //小于容差则选中 if (MinDistance < Convert.ToDouble(ToleranceTextBox.Text)) { IsPointSelected = true; PlotPointPictureBox.Cursor = CrossCur; SelectedPointIndex = MinDistanceIndex; DrawingTipLabel.Text = "已选中第" + Convert.ToString(SelectedPointIndex + 1) + "个点,按住鼠标左键拖动以改变位置,按Del或鼠标右键删除"; PolyLineDrawing.DrawPoints(Line.Points[SelectedPointIndex], PlotPointPictureBox, Algorithm.InverseColor(PointColorPictureBox.BackColor), Convert.ToInt32(PointWidthTrackBar.Value * 1.5)); PlotPointPictureBox.Refresh(); } else { if (SelectedPointIndex != -1) { ClearAndDraw(); } DisSelect(); DrawingTipLabel.Text = "未选中任何点"; } } //移动选中点 if (!IsDrawing && IsEditing && IsPointMoving && Line.Points.Count != 0) { if (e.X >= 0 && e.Y >= 0 && e.X <= PlotPointPictureBox.Width && e.Y <= PlotPointPictureBox.Height) { Line.Points[SelectedPointIndex].X = e.X; Line.Points[SelectedPointIndex].Y = e.Y; ClearAndDraw(); DrawingTipLabel.Text = "正在移动第" + Convert.ToString(SelectedPointIndex + 1) + "个点"; } else { DisSelect(); DrawingTipLabel.Text = "焦点丢失"; } } } catch (Exception err) { MessageBoxes.Error(err.Message); } }
//预览多边形绘制 internal static void DrawPolygon(List <PlotPoint> Points, PictureBox TargetPictureBox, Color PolygonColor, int PolygonTransparency, PlotPoint PreviewingPoint) { Graphics g = Graphics.FromImage(TargetPictureBox.BackgroundImage); g.SmoothingMode = SmoothingMode.AntiAlias; Brush PolygonBrush = new SolidBrush(Color.FromArgb(PolygonTransparency, PolygonColor.R, PolygonColor.G, PolygonColor.B)); List <PointF> PolygonPoints = new List <PointF>(); for (int i = 0; i < Points.Count; i++) { PolygonPoints.Add(new PointF { X = Points[i].X, Y = Points[i].Y }); } PolygonPoints.Add(new PointF { X = PreviewingPoint.X, Y = PreviewingPoint.Y }); g.FillPolygon(PolygonBrush, PolygonPoints.ToArray()); }
//计算单条线段长度 internal static double GetSingleLineLength(PlotPoint StartPoint, PlotPoint EndPoint) { return(Math.Sqrt(Math.Pow((EndPoint.X - StartPoint.X), 2) + Math.Pow((EndPoint.Y - StartPoint.Y), 2))); }
//将点移至控件中心为原点坐标系 internal static PlotPoint GetActualPos(PictureBox TargetPictureBox, PlotPoint Points) { Points.X -= (TargetPictureBox.Width / 2); Points.Y = (TargetPictureBox.Width / 2) - Points.Y; return(Points); }