zoukankan      html  css  js  c++  java
  • 已知圆心和两点画圆弧(算法)(计算机图形)(C#)

    如题,已经知道圆心和两点,画出两点间的圆弧,思路,先分别求出原点到两点向量和x轴间的夹角余弦值,然后求反余弦得出角度,这里要注意的是,求出的向量的夹角是按几何坐标系中定义的逆时针,然后用DrawArc()函数画圆弧。
    如图的三点:o(200,200),a(100,100),b(300,100)
    求夹角的方法是使用高中学过的向量求夹角公式:
    通过该公式,很方便地求出a,b向量的夹角的余弦值,然后使用反余弦函数求出弧长,然后用弧长radian*(180/pi)求出几何坐标系中的夹角。
    这个时候值得注意的是C#里面GDI+使用的坐标体系与常用的几何坐标系有所不同,所以画圆弧使用DrawArc()函数的时候要小心,从MSDN中可以看到DrawArc()的用法:
    C#
    public void DrawArc (Pen pen,float x,float y,float width,float height,float startAngle,float sweepAngle)
    参数
    pen
    Pen,它确定弧线的颜色、宽度和样式。
    x
    定义椭圆的矩形的左上角的 x 坐标。
    y
    定义椭圆的矩形的左上角的 y 坐标。
    width
    定义椭圆的矩形的宽度。
    height
    定义椭圆的矩形的高度。
    startAngle
    从 x 轴到弧线的起始点沿顺时针方向度量的角(以度为单位)。
    sweepAngle
    startAngle 参数到弧线的结束点沿顺时针方向度量的角(以度为单位)。
     
     
     
     
    这里的startAngle 是从 x 轴到弧线的起始点沿顺时针方向度量的角,而不是几何坐标体系中的逆时针所以使用startAngle 的时候,要在原来的坐标体系值加上90度,下面贴出源程序:
    运行情况为:
     
     
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    namespace draw
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
               
            }
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                //三个点,O为原点,A、B为圆上另外两点
                Point Point_O = new Point(200, 200);
                Point Point_A = new Point(100, 100);
                Point Point_B = new Point(300, 100);
                //x轴上的向量
                int Vector_Xx = 100;
                int Vector_Xy = 0;
                //oa向量
                int Vector_ax = Point_A.X - Point_O.X;
                int Vector_ay = Point_A.Y - Point_O.Y;
                //ob向量
                int Vector_bx = Point_B.X - Point_O.X;
                int Vector_by = Point_B.Y - Point_O.Y;
                //oa和X轴上向量的点乘积
                int Point_Mul_a = (Vector_ax * Vector_Xx) + (Vector_ay * Vector_Xy);
                double Mul_a = Math.Sqrt(Vector_ax * Vector_ax + Vector_ay * Vector_ay) * Math.Sqrt(Vector_Xx * Vector_Xx + Vector_Xy * Vector_Xy);
               
               
                //计算oa和x轴夹角余弦值
                double Cos_a = Point_Mul_a / Mul_a;
                double A_Cos = Math.Acos(Cos_a);
                //求出几何坐标系中的角度,即按逆时针的方法
                double A_Angle = A_Cos * (180 / Math.PI);

                //b和X轴上向量的点乘积
                int Point_Mul_b = (Vector_bx * Vector_Xx) + (Vector_by * Vector_Xy);
                double Mul_b = Math.Sqrt(Vector_bx * Vector_bx + Vector_by * Vector_by) * Math.Sqrt(Vector_Xx * Vector_Xx + Vector_Xy * Vector_Xy);
                ////计算b和x轴夹角余弦值
                double Cos_b = Point_Mul_b / Mul_b;
                double B_Cos = Math.Acos(Cos_b);
                //求出几何坐标系中的角度,即按逆时针的方法
                double B_Angle = B_Cos * (180 / Math.PI);

                //初始化画板
                Graphics gr = this.CreateGraphics();
                Brush br = new SolidBrush(Color.Black);
                Pen pe = new Pen(Color.Black, 10);
                //画出原点
                gr.FillEllipse(br,200,200,7,7);

                //画出圆弧
                gr.DrawArc(pe, 100, 100, 200, 200, (float)(A_Angle+90), (float)(A_Angle-B_Angle));
               
            }
        }
    }
     
    程序后的思考:本程序没有关心圆弧到底是劣弧还是优弧,要视使用情况而定。

    本文出自 “waster” 博客,http://waster.blog.51cto.com/117583/82851

  • 相关阅读:
    [Leetcode] Maximum Gap
    [Leetcode] Reverse Integer
    [Leetcode] Pow(x, n)
    Theano2.1.21-基础知识之theano中多核的支持
    Theano2.1.3-基础知识之更多的例子
    Theano2.1.17-基础知识之剖析theano的函数
    Theano2.1.16-基础知识之调试:常见的问题解答
    Theano2.1.15-基础知识之theano如何处理shapre信息
    Theano2.1.14-基础知识之理解为了速度和正确性的内存别名
    Theano2.1.13-基础知识之PyCUDA、CUDAMat、Gnumpy的兼容
  • 原文地址:https://www.cnblogs.com/stalwart/p/1897636.html
Copyright © 2011-2022 走看看