道路曲线线路坐标计算 ∈ C# 编程笔记

更新日期:2020/5/17

【注1】其中的代码也许并不完整,您可以作为伪码参看,或者您可以去我主博客逛逛,也许有意外之喜!
【注2】此篇博客是 C# 编程笔记 的子博客。

上一篇: 坐标转换 四参数/正形变换/七参数 回到 主博客 下一篇:—

3、曲线线路坐标计算

(我来现学现卖一下,2020/4/6)
道路的走向和线形受到各种因素的制约,线路在平面上或竖直面上不可能一条直线。平面上的称为平曲线,竖直面上的坡度变化称为竖曲线。下面对圆曲线和带缓和曲线的圆曲线的算法做一个简要的介绍。

3.1 圆曲线

3.1.1 原理

圆曲线的构成如下图所示:
在这里插入图片描述
主点有:直圆点、圆直点、曲中点、交点;用字母表示为:YZ, ZY, QZ, JD
主要的曲线要素有:线路转向角α、圆曲线半径R、切线长T(交点至直圆点或圆直点的长度)、曲线长L (由直圆点经中点至圆直点的弧长)、外矢距E (交点至圆曲线中点QZ的距离)和切曲差q (切线长和曲线之差)称圆曲线的曲线要素。只要知道了圆曲线的上述6个要素就可以计算和实地放样了。
实际上,只要知道Rα就可以知道所有的曲线要素了。
在这里插入图片描述
至此,基本元素已经计算完成,下面开始根据所给点的里程计算坐标。关于里程,这里多说一句。里程格式:DK a+b m;其中a代表公里数,b代表不足一公里的小数,整体来看就是当前点(按照路线走)到原点的距离为:1000*a+b (m)
第一步:计算线点独立坐标
在这里插入图片描述
如图,以ZY为原点,ZY->O为y轴,圆切线为x轴;以YZ为原点,YZ->O为y轴,圆切线为x轴分别建立平面直角坐标系。圆曲线上一点i在其中的坐标称之为其独立坐标。为什么要建立两个坐标系呢?其实是为了和计算带缓和曲线的圆曲线坐标相照应,圆曲线上无论哪点在两个坐标系上算出的精度都是一样的(理直气壮:我们老师说的!)。所以编程时就只用了左边的坐标系。
ZY到i点的弧长Li
在这里插入图片描述

3.1.2 代码实现:

        /*此函数用于计算简单圆曲线
         * 输入:R 半径; a 线路转向角; JD 交点里程; DQ 代求点里程数组; YZD 已知点数组; pd 前定向(q) 右偏(r)(默认)
         * 输出:row1: 0 半径; 1 偏角; 2 T; 3 L; 4 E; 5 q; 6 JD; 7 ZY; 8 QZ; 9 YZ; 10 代求点个数; 11 12 圆直点坐标;
         *       row2: 0 1 交点坐标; 2 3 定向点坐标; 4 5 直圆点坐标; 6..  代求点里程
         *       row3: 各个点的x, y坐标(独立)
         *       row4: 各个点的X, Y坐标(线路)
         */
        public static double[,] YQX_D(double R, Angle a, DK JD, DK[] DQ, Point[] YZD, string pd = "qr")
        {
            pd = pd.ToLower();
            char dx = pd[0]; if (dx != 'h') dx = 'q';//默认前定向
            char px = pd[1]; if (px != 'l') px = 'r';//默认右偏
            int mod = 1; if (px == 'l') mod = -1;//左右偏向的状态参量
            int m, n = DQ.Length;//代求坐标个数
            if (n > 6) m = 2 * n; else m = 13;
            double[,] result_dArray = new double[4, m];
            Angle a2 = a / 2;
            double T = R * a2.tan;//圆曲线切线长
            double L = R * a.rad;//曲线长
            double E = R * (a2.sec - 1);//曲线外矢距
            double q = 2 * T - L;//切曲差
            DK ZY = JD - T;//直圆点里程
            DK QZ = ZY + L / 2;//曲中点里程
            DK YZ = ZY + L;//圆直点里程
            result_dArray[0, 0] = R;
            result_dArray[0, 1] = a.rad; ;
            result_dArray[0, 2] = T;
            result_dArray[0, 3] = L;
            result_dArray[0, 4] = E;
            result_dArray[0, 5] = q;
            result_dArray[0, 6] = JD.a;
            result_dArray[0, 7] = ZY.a;
            result_dArray[0, 8] = QZ.a;
            result_dArray[0, 9] = YZ.a;
            result_dArray[0, 10] = n;
            
            Point p_JD = YZD[0];//YZD[0]为交点
            Point p_ZD = YZD[1];//YZD[1]为控制点
            result_dArray[1, 0] = p_JD.x;
            result_dArray[1, 1] = p_JD.y;
            result_dArray[1, 2] = p_ZD.x;
            result_dArray[1, 3] = p_ZD.y;

            for (int i = 0; i < n; i++)
            {
                result_dArray[1, 6 + i] = DQ[i].a;
            }
            Angle _a, _a1, PI = new Angle(Math.PI);
            if (dx == 'q')
            {
                _a = new Angle(arctan((p_JD.x - p_ZD.x), (p_JD.y - p_ZD.y)));//定向角
                if (px == 'r')//右偏
                    _a1 = _a + a + PI;
                else
                    _a1 = _a - a + PI;
            }
            else
            {
                _a1 = new Angle(arctan((p_JD.x - p_ZD.x), (p_JD.y - p_ZD.y)));//定向角
                if (px == 'r')//右偏
                    _a = _a1 - a - PI;
                else
                    _a = _a1 + a + PI;
            }

            Matrix _R = (-_a).R2, _R1 = (-_a1).R2;//旋转矩阵
            Point p_ZY = new Point(), p_YZ = new Point();
            p_ZY.x = p_JD.x - T * _a.cos; p_ZY.y = p_JD.y - T * _a.sin;
            p_YZ.x = p_JD.x - T * _a1.cos; p_YZ.y = p_JD.y - T * _a1.sin;
            result_dArray[0, 11] = p_YZ.x; result_dArray[0, 12] = p_YZ.y;
            result_dArray[1, 4] = p_ZY.x; result_dArray[1, 5] = p_ZY.y; 
            for (int i = 0; i < n; i++)
            {
                DK dq = DQ[i];
                if (dq < ZY || dq > YZ) continue;//不在圆曲线上的不用这个算
                double Li;
                Angle fi;
                Matrix zb = new Matrix(2, 1), ZB;
                if (dq < QZ)
                {
                    Li = dq.a - ZY.a;
                    fi = new Angle(Li / R);
                    zb[0, 0] = R * fi.sin;//独立坐标
                    zb[1, 0] = R * (1 - fi.cos);
                    result_dArray[2, 2 * i] = zb[0, 0];
                    result_dArray[2, 2 * i + 1] = zb[1, 0];
                    zb[1, 0] *= mod;
                    ZB = _R * zb;
                    result_dArray[3, 2 * i] = p_ZY.x + ZB[0, 0];
                    result_dArray[3, 2 * i + 1] = p_ZY.y + ZB[1, 0];
                }
                else
                {
                    Li = YZ.a - dq.a;
                    fi = new Angle(Li / R);
                    zb[0, 0] = R * fi.sin;//独立坐标
                    zb[1, 0] = R * (1 - fi.cos);
                    result_dArray[2, 2 * i] = zb[0, 0];
                    result_dArray[2, 2 * i + 1] = zb[1, 0];
                    zb[1, 0] *= (-1);
                    zb[1, 0] *= mod;
                    ZB = _R1 * zb;
                    result_dArray[3, 2 * i] = p_YZ.x + ZB[0, 0];
                    result_dArray[3, 2 * i + 1] = p_YZ.y + ZB[1, 0];
                }
            }
            return result_dArray;
        }
        /*此函数用于输出 简单圆曲线计算结果
         */ 
        public static void OutPut_D(double[,] M)
        {
            int n = (int)M[0, 10];
            Console.WriteLine("R={0:f3}      半径", M[0, 0]);
            Console.WriteLine("a={0:f3}      线路转向角", M[0, 1]);
            Console.WriteLine("T={0:f3}      切线长", M[0, 2]);
            Console.WriteLine("L={0:f3}      曲线长", M[0, 3]);
            Console.WriteLine("E={0:f3}      外矢距", M[0, 4]);
            Console.WriteLine("q={0:f3}      切曲差", M[0, 5]);
            Console.WriteLine("KJD={0:f3}    交点里程", M[0, 6]);
            Console.WriteLine("KZY={0:f3}    直圆点里程", M[0, 7]);
            Console.WriteLine("KQZ={0:f3}    曲中点里程", M[0, 8]);
            Console.WriteLine("KYZ={0:f3}    圆直点里程", M[0, 9]);
            Console.WriteLine("JD  X={0:f4}, Y={1:f4}    JD坐标", M[1, 0], M[1, 1]);
            Console.WriteLine("ZD  X={0:f4}, Y={1:f4}    ZD坐标", M[1, 2], M[1, 3]);
            Console.WriteLine("ZY  X={0:f4}, Y={1:f4}    ZY坐标", M[1, 4], M[1, 5]);
            Console.WriteLine("YZ  X={0:f4}, Y={1:f4}    YZ坐标", M[0, 11], M[0, 12]);
            Console.WriteLine();
            Console.WriteLine("n={0:f3}      代求点个数", M[0, 10]);
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("nu:{0}  K={1:f3},  x={2:f4},  y={3:f4}  ", i + 1, M[1,6+i], M[2, 2 * i], M[2, 2 * i+1]);
                Console.WriteLine("                   X={0:f4},  Y={1:f4}  ", M[3, 2 * i], M[3, 2 * i + 1]);
            }
        }

算例:
在这里插入图片描述

3.1.3 调用示例:

			double R = 490;                 //半径
            Angle a = new Angle(26, 58, 31);//偏向角
            DK JD = new DK(1, 523.600);     //交点里程
            DK[] DQ = new DK[1];            //带求坐标里程
            DQ[0] = new DK(1, 430);       //右偏时用到
            //DQ[0] = new DK(1, 612.842);     //左偏时用到
            Point[] yzd = new Point[2];     //已知点坐标  0 JD坐标 1 定向点坐标
            yzd[0] = new Point(9018.059, 3665.385);
            yzd[1] = new Point(8936.445, 3517.359);//右前、左后用到
            //yzd[1] = new Point(9023.059, 3816.519);  //右后、左前用到
            double[,] M = curveLine.YQX_D(R, a, JD, DQ, yzd, "qr");
            curveLine.OutPut_D(M);

            Console.Read();

程序输出结果更详细了,下图是2.0版本,代码是3.0版本
在这里插入图片描述

3.2 带缓和曲线的圆曲线

3.2.1 原理

缓和曲线是直线与圆曲线之间或半径相差较大的两个转向相同的圆曲线之间介入的一段曲率半径由∞渐变至圆曲线半径R的一种线型,它起缓和及过渡的作用。
在这里插入图片描述
如图,其主点有:直缓点ZH、缓圆点HY、曲中点QZ、圆缓点YH、缓直点HZ
曲线参数有:β0为缓和曲线的切线角,即缓和曲线所对的中心角。自圆心向直缓点ZH或缓直点HZ的切线作垂线OCOD,并将圆曲线两端延长至垂线,则: m为直缓点ZH(或缓直点HZ)至垂足的距离,称为切垂距(也称切线增量); P为垂线长OCOD与圆曲线半径R之差,称为圆曲线内移量。
曲线综合要素有:线路转向角a、圆曲线半径R、缓和曲线长Ls,、切线长TH、曲线长LH、外矢距EH和切曲差q。即在圆曲线的曲线要素基础上加缓和曲线长Ls
已知线路转向角a、圆曲线半径R、缓和曲线长Ls后,可计算:
在这里插入图片描述
至此,基本元素已经计算完成,下面开始根据所给点的里程计算坐标。
第一步:计算线点独立坐标
在这里插入图片描述
如图:以ZH为原点,ZH->O为y轴,切线为x轴;以HZ为原点,HZ->O为y轴,切线为x轴分别建立平面直角坐标系。现在用两个坐标系就十分有必要了,以QZ为分界线,下分别介绍圆曲线上一点i在其中的坐标计算方法。
X’O’Y’中,i点至ZH的弧长Li
在这里插入图片描述
第二步:计算ZH、HZ点坐标
JD的线路坐标为(XJD,YJD) ZHJD点的线路坐标方位角为αZHHZ点到JD点的线路坐标方位角为αHZ,所以ZY、YZ点线路坐标为:
在这里插入图片描述
这里必须要说明一个问题:无论是简单圆曲线,还是带缓和曲线的圆曲线,线路有向左偏的,有向右偏的,为了将代码做的更加完整,必须要考虑清楚如下问题:
在这里插入图片描述
右偏前定向和左偏后定向得到的位置相对关系是一样的,实际上,很少有后定向的情况,因为我们是用已知放样未知,我们用的肯定是已经在实地存在的点来放样规划图上的点。在图中具体可以得到什么信息这里就不在赘述(我怕自己又绕进去)
详细介绍可以参看教材:《工程测量学》第二版 张正禄主编 P114

3.2.2 代码实现:

        /*此函数用于计算带缓和曲线的圆曲线
         * 输入:R 半径; a 线路转向角; Ls 缓和曲线长; JD 交点里程; DQ 代求点里程数组; YZD 已知点数组; pd 前定向(q) 右偏(r)(默认)
         * 输出:row1: 0 半径; 1 偏角; 2 m; 3 P; 4 beta0; 5 TH; 6 Ls; 7 Lh; 8 Lt; 9 E; 10 q
         *             11 JD; 12 ZH; 13 HY; 14 QZ; 15 YH; 16 HZ; 17 代求点个数
         *       row2: 0 1 交点坐标; 2 3 定向点坐标; 4 5 直缓点坐标; 6 7 缓直点坐标; 8.. 代求点里程      
         *       row3: 各个点的x, y坐标(独立)
         *       row4: 各个点的X, Y坐标(线路)
         */
        public static double[,] YQX_H(double R, Angle a, double Ls, DK JD, DK[] DQ, Point[] YZD, string pd = "qr")
        {
            pd = pd.ToLower();
            char dx = pd[0]; if (dx != 'h') dx = 'q';//默认前定向 防止输错
            char px = pd[1]; if (px != 'l') px = 'r';//默认右偏
            int mod = 1; if (px == 'l') mod = -1;//左右偏向的状态参量
            int num, n = DQ.Length;//代求坐标个数
            if (n > 9) num = 2 * n; else num = 18;
            double[,] result_dArray = new double[4, num];
            Angle a2 = a / 2;
            double m = Ls / 2 - P(Ls, 3) / (240 * R * R),//切垂距
                P1 = Ls * Ls / (24 * R),//圆曲线内移值
                beta0 = Ls / (2 * R);//缓和曲线切线角
            double T = (R + P1) * a2.tan + m;//切线长
            double Lh = R * (a.rad - 2 * beta0) + 2 * Ls;//整个曲线长
            double Lt = Lh - 2 * Ls;//圆曲线长
            double E = (R + P1) * a2.sec - R;//曲线外矢距
            double q = 2 * T - Lh;//切曲差
            DK ZH = JD - T;//直缓点里程
            DK HY = ZH + Ls;//缓圆点里程
            DK QZ = ZH + Lh * 0.5;//曲中点里程
            DK YH = HY + Lt;//圆直点里程
            DK HZ = YH + Ls;//缓直点里程
            result_dArray[0, 0] = R;
            result_dArray[0, 1] = a.rad;
            result_dArray[0, 2] = m;
            result_dArray[0, 3] = P1;
            result_dArray[0, 4] = beta0;
            result_dArray[0, 5] = T;
            result_dArray[0, 6] = Ls;
            result_dArray[0, 7] = Lh;
            result_dArray[0, 8] = Lt;
            result_dArray[0, 9] = E;
            result_dArray[0, 10] = q;
            result_dArray[0, 11] = JD.a;
            result_dArray[0, 12] = ZH.a;
            result_dArray[0, 13] = HY.a;
            result_dArray[0, 14] = QZ.a;
            result_dArray[0, 15] = YH.a;
            result_dArray[0, 16] = HZ.a;
            result_dArray[0, 17] = n;
            Point p_JD = YZD[0];//YZD[0]为交点
            Point p_ZD = YZD[1];//YZD[1]为定向点
            result_dArray[1, 0] = p_JD.x;
            result_dArray[1, 1] = p_JD.y;
            result_dArray[1, 2] = p_ZD.x;
            result_dArray[1, 3] = p_ZD.y;
            for (int i = 0; i < n; i++)
            {
                result_dArray[1, 8 + i] = DQ[i].a;
            }
            Angle _a, _a1, PI = new Angle(Math.PI);
            if (dx == 'q')
            {
                _a = new Angle(arctan((p_JD.x - p_ZD.x), (p_JD.y - p_ZD.y)));//定向角
                if (px == 'r')//右偏
                    _a1 = _a + a + PI;
                else
                    _a1 = _a - a + PI;
            }
            else
            {
                _a1 = new Angle(arctan((p_JD.x - p_ZD.x), (p_JD.y - p_ZD.y)));//定向角
                if (px == 'r')//右偏
                    _a = _a1 - a + PI;
                else
                    _a = _a1 + a + PI;
            }
            Matrix _R = (-_a).R2, _R1 = (-_a1).R2;//旋转矩阵
            Point p_ZH = new Point(), p_HZ = new Point();
            p_ZH.x = p_JD.x - T * _a.cos; p_ZH.y = p_JD.y - T * _a.sin;
            p_HZ.x = p_JD.x - T * _a1.cos; p_HZ.y = p_JD.y - T * _a1.sin;
            result_dArray[1, 4] = p_ZH.x;
            result_dArray[1, 5] = p_ZH.y;
            result_dArray[1, 6] = p_HZ.x;
            result_dArray[1, 7] = p_HZ.y;
            for (int i = 0; i < n; i++)
            {
                DK dq = DQ[i];
                if (dq < ZH || dq > HZ) continue;//不在曲线上的不用这个算
                Matrix zb = new Matrix(2, 1), ZB;//独立坐标
                double Li; Angle fi;
                if (dq < QZ)
                {//前半段
                    if (dq < HY)
                    {//在缓和曲线上
                        Li = dq.a - ZH.a;
                        zb[0, 0] = Li - P(Li, 5) / (40 * R * R * Ls * Ls);
                        zb[1, 0] = P(Li, 3) / (6 * R * Ls);
                    }
                    else
                    {//在圆曲线上
                        Li = dq.a - ZH.a;
                        fi = new Angle((Li - 0.5 * Ls) / R);
                        zb[0, 0] = m + R * fi.sin;//独立坐标
                        zb[1, 0] = P1 + R * (1 - fi.cos);
                    }
                    result_dArray[2, 2 * i] = zb[0, 0];
                    result_dArray[2, 2 * i + 1] = zb[1, 0];
                    zb[1, 0] *= mod;
                    ZB = _R * zb;
                    result_dArray[3, 2 * i] = p_ZH.x + ZB[0, 0];
                    result_dArray[3, 2 * i + 1] = p_ZH.y + ZB[1, 0];
                }
                else
                {//后半段
                    if (dq > YH)
                    {//在缓和曲线上
                        Li = HZ.a - dq.a;
                        zb[0, 0] = Li - P(Li, 5) / (40 * R * R * Ls * Ls);
                        zb[1, 0] = P(Li, 3) / (6 * R * Ls);
                    }
                    else
                    {//在圆曲线上
                        Li = HZ.a - dq.a;
                        fi = new Angle((Li - 0.5 * Ls) / R);
                        zb[0, 0] = m + R * fi.sin;//独立坐标
                        zb[1, 0] = P1 + R * (1 - fi.cos);
                    }
                    result_dArray[2, 2 * i] = zb[0, 0];
                    result_dArray[2, 2 * i + 1] = zb[1, 0];
                    zb[1, 0] = -zb[1, 0];//后半段
                    zb[1, 0] *= mod;     //左右偏
                    ZB = _R1 * zb;
                    result_dArray[3, 2 * i] = p_HZ.x + ZB[0, 0];
                    result_dArray[3, 2 * i + 1] = p_HZ.y + ZB[1, 0];
                }
            }
            return result_dArray;
        }
        /*此函数用于输出 带缓和曲线的圆曲线计算结果
         */
        public static void OutPut_H(double[,] M)
        {
            int n = (int)M[0, 17];
            Console.WriteLine("R={0:f3}      半径", M[0, 0]);
            Console.WriteLine("a={0:f3}      线路转向角", M[0, 1]);
            Console.WriteLine("m={0:f3}      切垂距", M[0, 2]);
            Console.WriteLine("P={0:f3}      圆曲线内移量", M[0, 3]);
            Console.WriteLine("beta0={0:f3}  缓和曲线的切线角", M[0, 4]);
            Console.WriteLine("TH={0:f3}     切线长", M[0, 5]);
            Console.WriteLine("Ls={0:f3}     缓和曲线长", M[0, 6]);
            Console.WriteLine("LH={0:f3}     曲线长", M[0, 7]);
            Console.WriteLine("Lt={0:f3}     圆曲线长", M[0, 8]);
            Console.WriteLine("E={0:f3}      外矢距", M[0, 9]);
            Console.WriteLine("q={0:f3}      切曲差", M[0, 10]);
            Console.WriteLine("KJD={0:f3}    交点里程", M[0, 11]);
            Console.WriteLine("KZH={0:f3}    直缓点里程", M[0, 12]);
            Console.WriteLine("KHY={0:f3}    缓圆点里程", M[0, 13]);
            Console.WriteLine("KQZ={0:f3}    曲中点里程", M[0, 14]);
            Console.WriteLine("KYH={0:f3}    圆缓点里程", M[0, 15]);
            Console.WriteLine("KHZ={0:f3}    缓直点里程", M[0, 16]);
            Console.WriteLine("JD  X={0:f4}, Y={1:f4}    JD坐标", M[1, 0], M[1, 1]);
            Console.WriteLine("ZD  X={0:f4}, Y={1:f4}    ZD坐标", M[1, 2], M[1, 3]);
            Console.WriteLine("ZH  X={0:f4}, Y={1:f4}    ZH坐标", M[1, 4], M[1, 5]);
            Console.WriteLine("HZ  X={0:f4}, Y={1:f4}    HZ坐标", M[1, 6], M[1, 7]);
            Console.WriteLine();
            Console.WriteLine("n={0:f3}      代求点个数", M[0, 17]);
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("nu:{0}  K={1:f3},  x={2:f4},  y={3:f4}  ", i + 1, M[1, 8 + i], M[2, 2 * i], M[2, 2 * i + 1]);
                Console.WriteLine("                   X={0:f4},  Y={1:f4}  ", M[3, 2 * i], M[3, 2 * i + 1]);
            }
        }

算例:
在这里插入图片描述

3.2.3 使用示例:

            double R = 854.4;                 //半径
            Angle a = new Angle(42, 18, 25.2);//转向角
            double Ls = 85;                   //缓和曲线长
            DK JD = new DK(24, 471.762);      //交点里程
            DK[] DQ = new DK[1];              //代求点里程数组
            DQ[0] = new DK(24, 750);//右偏里程
            //DQ[0] = new DK(24, 162.94);//左偏里程
            Point[] yzd = new Point[2];       //已知点坐标  0 JD坐标 1 定向点坐标
            yzd[0] = new Point(399606.2286, 539444.3196);
            yzd[1] = new Point(399589.5506, 538373.6835);//右前、左后
            //yzd[1] = new Point(399106.2286,540011.1685);//右后、左前
            double[,] M = curveLine.YQX_H(R, a, Ls, JD, DQ, yzd, "qr");
            curveLine.OutPut_H(M);
            Console.Read();

程序输出结果更详细了,下图是2.0版本,代码是3.0版本
在这里插入图片描述
里面所用角类和里程类链接:
https://blog.csdn.net/Gou_Hailong/article/details/95803595
程序框架图:
在这里插入图片描述
上一篇: 坐标转换 四参数/正形变换/七参数 回到 主博客 下一篇:—

【注1】其中的代码也许并不完整,您可以作为伪码参看,或者您可以去我主博客逛逛,也许有意外之喜!
【注2】此篇博客是 C# 编程笔记 的子博客。
【注3】由于博主水平有限,程序可能存在漏洞或bug, 如有发现,请尽快与博主联系!
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪猪头拯救地球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值