G代码圆弧_g02和g03走圆编程-程序员宅基地

技术标签: 算法  G-Code  兴趣使然  G02/G03  

圆弧总结

说明

工作中经常画图经常会遇到圆弧,开始的时候我并不是很理解,随着深入发现其实有些坑的,这里总结记录一下,可能并不是最优的解法,但肯定是自己理解后想出来的,如果这些能给你提供一些思路和帮助,那便是极好的。

G-Code的G02/G03

G02 顺时针圆弧/G03 逆时针圆弧

在这里插入图片描述

圆心的计算

I, J, K模式
G02 X20 Y10 I0 J-10
G03 X10.5 I3.0 J4.0

G02/G03指令,是已知起始点S(Xs, Ys),终止点E(Xe, Ye),相对圆心的增量(I, J),顺逆时针状态。通过这些信息我们是可以算出圆心的。

一般来说是(I, J)是圆弧起点相对圆心的增量,即圆心O坐标是(Xs + I, Ys + J)。而我遇到的情况,(I, J)的表示可能有以下几种情况:

  • 相对圆弧起点的增量
  • 相对圆弧终点的增量
  • 绝对圆弧中心
计算

这个就很简单了,针对(I, J)表示不同时计算方式也不同

  • 相对圆弧起点时,圆心坐标

O x = X s + I ; O y = Y s + J ; O_x = X_s + I;\\ O_y = Y_s + J;\\ Ox=Xs+I;Oy=Ys+J;

  • 相对圆弧终点时,圆心坐标

O x = X e + I ; O y = Y e + J ; O_x = X_e + I;\\ O_y = Y_e + J;\\ Ox=Xe+I;Oy=Ye+J;

  • 绝对圆弧中心

O x = I ; O y = J ; O_x = I;\\ O_y = J; Ox=I;Oy=J;

R模式
G02 X20 Y10 R10 F300

注意相同的起点、终点、半径和方向,计算出来的圆心可能有两种。其中,

  • R>0时,圆弧和中心的夹角小于180°,即圆弧段小于或等于半圆;
  • R<0时,圆弧和中心的夹角大于180°,即圆弧段大于半圆。

例如下图,G02指令时,如果R>0时,圆心是黑色圆的,如果R<0,则应该是黄色的圆。
在这里插入图片描述

以下图片是我画的分析用的简易图,方便自己理解如何计算出圆心的方法。假设以下是G02圆弧,起点为C,终点为D,半径为R,加粗圆弧部分是实际路径。
在这里插入图片描述

计算

假设存在上面的情况,已知起点C(Xc, Yc), 终点D(Xd, Yd),半径R

  1. 连接CD,求得中点A(Xa, Ya)

X a = ( X c + X d ) 2 Y a = ( Y c + Y d ) 2 (1) X_a = \frac{(X_c + X_d)}{2}\\ Y_a = \frac{(Y_c + Y_d)}{2} \tag{1} Xa=2(Xc+Xd)Ya=2(Yc+Yd)(1)

  1. 现在可以得到向量 A C ⃗ \vec{AC} AC 的单位向量了
    ∣ A C ⃗ ∣ = ( X a − X c ) 2 + ( Y a − Y c ) 2 A C ^ = A C ⃗ ∣ A C ⃗ ∣ (2) |\vec{AC}| = \sqrt{(X_a - X_c)^2 + (Y_a - Y_c)^2} \\ \hat{AC} = \frac{\vec{AC}}{|\vec{AC}|} \tag{2} AC =(XaXc)2+(YaYc)2 AC^=AC AC (2)

  2. 圆上两点连线的中垂线必过圆心,这是个知识点,然后根据直角三角关系,可以知道(AO)2 = R2 - (AC)2,下面用向量的方式表示,后面会用到。

∣ A O ⃗ ∣ = R 2 − ∣ A C ⃗ ∣ 2 (3) |\vec{AO}| = \sqrt{R^2 - |\vec{AC}|^2} \tag{3} AO =R2AC 2 (3)

  1. 现在只需要将单位向量 A C ^ \hat{AC} AC^,旋转90°后就是向量 A O ⃗ \vec{AO} AO 的单位向量(这个没问题吧),如果旋转-90°就是向量 A P ⃗ \vec{AP} AP 的单位向量,然后乘以AO的长度就得到圆心了,两种情况的圆心都可以认为是对的。

A O ⃗ = A O ^   ∗ ∣ A O ⃗ ∣ (4) \vec{AO} = \hat{AO}\ * |\vec{AO}|\tag{4} AO =AO^ AO (4)

R模式实际算法省略,因为经验有限,我并没有遇到过这个情况,当前仅讨论这个情况下计算出圆心的理论算法。

圆弧夹角的计算

这个地方,我感觉相对是比较麻烦的,因为必须要考虑圆弧方向,角度的值域范围,并不能简单粗暴的 终点角度 − 起点角度 终点角度- 起点角度 终点角度起点角度

#define 	PI 		3.1415926535897932384626433
#define 	EPS 	0.000001

//!< 基础点
struct Point
{
    
	double x;
    double y;
};
typedef Point Vector;

//!< 计算两向量夹角
float calc2VecAngle(const Vector& v1, const Vector& v2, const int& isCw)
{
    
    //!< atan2 计算得到的弧度范围是[-PI, PI],可以转换成[0, 2 * PI]来计算
    float startAngNew = atan2f(v1.y, v1.x);
    float startAngNew2 = atan2f(v2.y, v2.x);

    if (startAngNew < EPS)
        startAngNew += 2 * PI;
    if (startAngNew2 < EPS)
        startAngNew2 += 2 * PI;

    float sweepNew = abs(startAngNew - startAngNew2);
    if (isCw != 0)
    {
    
        //!< 两向量之间的夹角,需要根据顺/逆时针,和所处角度象限判断
        if (startAngNew < startAngNew2 && isCw > EPS ||
            startAngNew > startAngNew2 && isCw < EPS)
        {
    
            sweepNew = abs(2 * PI - abs(sweepNew));
        }
    }
    return sweepNew;
}

//!< 已知圆弧,圆心,起点,终点,方向,计算出圆弧夹角(弧度制) 
void calcArcAngle(Point center, Point s, Point e, bool isClockWise, double& angle)
{
    
    //!< 起点终点相同的情况,就是个整圆
    if (s == e)
    {
    
        angle = PI * 2;
    }
    else
    {
    
        Vector v1, v2;
        v1.x = start.x - center.x;
        v1.y = start.y - center.y;

        v2.x = end.x - center.x;
        v2.y = end.y - center.y;

        angle = calc2VecAngle(v1, v2, (cw ? 1 : -1));
    }
}

在圆弧上

上面的方法中,可以已知圆弧圆心,圆弧起点,圆弧终点,方向,是可以计算判断出某个点在不在圆弧上。

//!< 两点的距离
double getLength(const Point& p1, const Point& p2)
{
    
	return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));   
}

//!< 计算角度,需要用到atan2f值域[-π, π],这个很重要
//!< 可以转换成[0, 2π]来计算
double getAngle(const Point& p1, const Point& p2)
{
    
    double ang = atan2f((p2.y - p1.y), (p2.x - p1.x)); // [-π, π]
    if (ang < EPS) {
         // [-π, 0]
        ang += PI * 2.0f;
    }
    return ang;
}

//!< angle的取值限制为圆上的任意角度
bool isOn(const Point& center, const Point& start, const Point& end, const bool& cw, const double& angle, const double& eps)
{
    
    //!< 如果圆是个整圆,任一角度都在圆弧上
    if (start == end)
    {
    
        return true;
    }

    //[0, 2π]
    double startAng = getAngle(center, start);
    double endAng = getAngle(center, end);
    double curAng = angle;

    bool bIsOn = false;
    //!< 顺时针
    if (cw)
    {
    
        //!< 圆弧起始角度 > 终止角度的情况
        if (startAng > endAng)
        {
    
            //!< curAng 满足区间 [endAng, startAng]
            if (curAng >= endAng && curAng <= startAng)
            {
    
                bIsOn = true;
            }
        }
        //!< 圆弧起始角度 < 终止角度
        else
        {
    
            //!< 顺时针时 起始角度 < 终止角度则说明圆弧经过了0°, 则此时可以
            //!< 在两个区间判断角度, 满足任一区间即可, [endAng, 2π], [0, startAng]
            if ((curAng >= endAng && curAng <= 2*PI) ||
                (curAng >= eps && curAng <= startAng)
            {
    
                bIsOn = true;
            }
        }
    }
    //!< 逆时针
    else
    {
    
        //!< 圆弧起始角度 < 终止角度的情况
        if (startAng < endAng)
        {
    
            //!< curAng的值域在[startAng, endAng]
            if (curAng >= startAng && curAng <= endAng)
            {
    
                bIsOn = true;
            }
        }
        //!< 圆弧起始角度 > 终止角度
        else
        {
    
            //!< 逆时针时 起始角度 > 终止角度则说明圆弧经过了0°, 则此时可以
            //!< 在两个区间判断角度, 满足任一区间即可, [startAng, 2π], [0, endAng]
            if ((curAng >= startAng && curAng <= 2*PI) ||
                (curAng >= eps && curAng <= endAng)
            {
    
                bIsOn = true;
            }
        }
    }
    return bIsOn;
}

//!< 判断点是不是在圆弧上
bool isOn(const Point& center, const Point& start, const Point& end, const bool& cw, const Point& curPt, const double& eps)
{
    
    double radius = getLength(center, start);
    double len = getLength(center, pt);
    
    //!< 半径不匹配肯定是不在圆上的
    if (abs(len - radius) > eps)
        return false;

    double curAng = getAngle(m_center, pt);
	return isOn(center, start, end, cw, curAng, eps);
}

圆弧外接矩形计算

不带角度

下图中黑色圆弧为实际圆弧,黑色点为圆的四个顶点位置,绿色为需要计算的圆弧外接矩形,这个时候求圆弧外接矩形是分两种情况的:

  • 小于90°
    小于90°的圆弧

  • 大于等于90°
    大于90°的圆弧

计算
  1. 从圆的上下左右四个顶点中,找出在圆弧上的顶点
  2. 计算出已知点集的外接矩形
#define MAX_NUM  1E20
#define MIN_NUM  -1E20

//!< 外接矩形
struct rect
{
    
    float left;
    float top;
    float right;
    float bottom;
};

//!< 计算圆弧的外接矩形
rect calcRectangle(const Point& center, const Point& start, const Point& end, const bool& cw)
{
    
    rect rc;
    double radius = getLength(center, start);
    
    //!< 如果是个整圆
    if (start == end)
    {
    
        rc.left = center.x - radius;
        rc.right = center.x + radius;
        rc.top = center.y + radius;
        rc.bottom = center.y - radius;
    }
	else
    {
    
        std::vector<sPoint> vArcVertex;
        vArcVertex.push_back(start);
        vArcVertex.push_back(end);    

        //!< 判断圆的四个顶点是不是在圆弧上,在圆弧上的顶点参与计算外接矩形
        sPoint ptCirList[] = {
     center + Point(0, radius), 
            center + Point(radius, 0),
            center + Point(-radius, 0),
            center + Point(0, -radius) };
        for (int i = 0; i < 4; i++)
        {
    
            if (isOn(center, start, end, cw, ptCirList[i], EPS))
            {
    
                vArcVertex.push_back(ptCirList[i]);
            }
        }

        rc.right = rc.top = MIN_NUM;
        rc.left = rc.bottom = MAX_NUM;
        for (auto& pt : vArcVertex)
        {
    
            rc.left = min(rc.left, pt.x);
            rc.right = max(rc.right, pt.x);
            rc.top = max(rc.top, pt.y);
            rc.bottom = min(rc.bottom, pt.y);
        }        
    }
    return rc;
}

圆弧相对距离的点

在这里插入图片描述

//!< 根据某点旋转
void rotate(Point& src, const Point& center, const float& sweepAng)
{
    
    float xOrg = src.x, yOrg = src.y;
    src.x = center.x + (xOrg - center.x) * cos(angle) - (yOrg - center.y) * sin(angle);
    src.y = center.y + (xOrg - center.x) * sin(angle) + (yOrg - center.y) * cos(angle);
}

//!< 圆弧上以起点位置,计算相对偏移distance的点
Point getSatrtOffsetOnArc(const Point& center, const Point& start, const Point& end, const bool& cw, const float& distance)
{
    
    //!< 计算圆弧半径
    double radius = getLength(center, start);
    //!< 圆弧长度对应圆心角
	float sweepAng =  distance / radius;
	Point curPoint = start;
	if (cw)
        sweepAng = -sweepAng;

	rotate(curPoint, center, sweepAng);
	return curPoint;
}

圆弧与线段相交

在这里插入图片描述

计算
  1. 判断圆心到线段的最短距离是不是小于半径,大于半径的时候肯定是不会与圆弧相交的
  2. 求出圆弧与直线的交点,最多两个,需要满足既在圆弧上,也在线段上
//!< 判断点p是否在线段(s, e)上
bool isOnLineSeg(const Point& s, const Point& e, const Point& p, const float& eps)
{
    
    float c = getLength(s, e);
    float a = getLength(s, p);
    float b = getLength(e, p);
    //!< 构成三角形,运用定理两边之和大于第三边,等于第三边则构成线段,点p在线段上
    if (abs(a + b - c) < eps)
        return true;
    else
        return false;
}

//!< 求出圆弧与线段相交的交点
vector<Point> getArcLineSegCross(const Point& center, const Point& start, const Point& end, const bool& cw, const Point& s, const Point& e, const float& eps)
{
    
    float x1 = s.x;
    float y1 = s.y;
    float dx = e.x - s.x;
    float dy = e.y - s.y;

    float cx = center.x;
    float cy = center.y;
    float r = getLength(center, start);

    //!< 圆弧与直线相交,求得两交点的公式
    float a = dx * dx + dy * dy;
    float b = 2 * (dx * (x1 - cx) + dy * (y1 - cy));
    float c = (x1 - cx) * (x1 - cx) + (y1 - cy) * (y1 - cy) - r * r;

    vector<Point> vCrossPoint;
    float discriminant = b * b - 4 * a * c;
    if (discriminant > eps)
    {
    
        float t1 = (-b + sqrt(discriminant)) / (2 * a);
        float t2 = (-b - sqrt(discriminant)) / (2 * a);
        
        Point intersection1 = {
     x1 + t1 * dx, y1 + t1 * dy };
        Point intersection2 = {
     x1 + t2 * dx, y1 + t2 * dy };
		
        Point intersectionArray[] = {
    intersection1, intersection2};
        
        int resultSize = 2;
        //!< 相切的情况, 只有一个解
        if (abs(t1 - t2) < eps)
        {
    
            resultSize = 1;
        }
        
        for (int i = 0; i < resultSize; i++)
        {
    
            if (isOn(center, start, end, cw, intersectionArray[i], eps) &&
               isOnLineSeg(s, e, intersectionArray[i], eps))
            {
    
             	vCrossPoint.push(intersection1);   
            }
        }        
    }
    return vCrossPoint;
}

线段外与圆相切的问题

需要做的效果

在这里插入图片描述

已知
  1. 已知线段起点终点
  2. 鼠标位置
  3. 需要构建一个相切与该线段的圆,圆弧终点为鼠标当前点,起点为线段端点(就认为是起点吧)
计算
  1. 鼠标位置与线段端点连线组成线段AB,提前可知圆上任意两点连线即(AB)的中垂线必过圆心,所以AB的中垂线必过圆心
  2. 因为原线段需要与所求的圆弧相切,即原线段端点的垂线也必过该圆心
  3. 以上所得两直线的交点即为圆心
//!< 计算线段的中垂线
void getMidPerpendicularLine(const Point& s1, const Point& e1, Point& s2, Point& e2, const float& eps)
{
    
    Point midPoint = (s1 + e1) / 2.0f;
    float len = getLength(s1, e1) / 2.0f;
    if (abs(s1.x - e1.x) < eps && abs(s1.y - e1.y) < eps)
    {
    
        //!< 同一个点, 不做任何处理
    }
    else if (abs(s1.x - e1.x) < eps)
    {
    
        s2.x = midPoint.x;
        s2.y = midPoint.y + len;

        e2.x = midPoint.x;
        e2.y = midPoint.y - len;
    }
    else if (abs(s1.y - e1.y) < eps)
    {
    
        s2.x = midPoint.x + len;
        s2.y = midPoint.y;

        e2.x = midPoint.x - len;
        e2.y = midPoint.y;
    }
    else
    {
    
        //!< 沿着中点随便旋转90°都可以组成中垂线
        s2 = s1;
		rotate(s2, midPoint, PI / 2);
        
        e2 = e1;
		rotate(e2, midPoint, PI / 2);
    }
}

//!< 两直线求交点
bool getLineCross(const Point& p1, const Point& p2, const Point& p3, const Point& p4, sPoint& p, const float& eps)
{
    
    //!< 构建直线L1
    int sign = 1;
    double a1 = p2.y - p1.y;
    if (a1 < eps)
    {
    
        sign = -1;
        a1 = sign * a1;
    }
    double b1 = sign * (p1.x - p2.x);
    double c1 = sign * (p1.y * p2.x - p1.x * p2.y);

    //!< 构建直线L2
    sign = 1;
    double a2 = p4.y - p3.y;
    if (a2 < eps)
    {
    
        sign = -1;
        a2 = sign * a2;
    }
    double b2 = sign * (p3.x - p4.x);
    double c2 = sign * (p3.y * p4.x - p3.x * p4.y);

    //!< 求L1和L2的交点
    double d = a1 * b2 - a2 * b1;
    if (abs(d) < eps) // 不相交 
        return false;
    
    p.x = (c2 * b1 - c1 * b2) / d;
    p.y = (a2 * c1 - a1 * c2) / d;
    return true;
}

//!< 计算相切的圆弧, 假设以线段起点为圆弧起点,鼠标位置为圆弧终点来计算圆弧
//!< 这里需要注意的是,圆弧的方向,需要提前自己确定
void calcTangentArc(const Point& s, const Point& e, const Point& mousePos, Point& center, Point& arcStart, Point& arcEnd, const float& eps)
{
    
    //!< 过线段起点的垂线s, p1
    Point p1;
    rotate(e, s, PI / 2);
    
    //!< 线段的中垂线pArc1, pArc2
    Point pArc1, pArc2;
    getMidPerpendicularLine(s, mousePos, pArc1, pArc2, EPS);
    
    Point pArcCenter;
    //!< 如果有交点,算出圆心
    if (getLineCross(s, p1, pArc1, pArc3, pArcCenter, EPS))
    {
    
        center = pArcCenter;
        arcStart = s;
        arcEnd = mousePos;
    }
}
实现效果

下面的效果中,我是已知轮廓的方向的,所以做出了镜像的圆弧

在这里插入图片描述

圆弧分割成多线段

一些时候画圆弧+线段连起来的时候,一些API并并不能完美的画出来,起点是对的,终点会有些偏差,可能缩小的时候看不出来差别,放大到了节点处会出现断开的情况。一些做法画圆弧,不用画圆弧的函数来做,把圆弧分成很多个线段,连起来。这样起点和终点可以保证正确。

//!< 圆弧分割成多线段集
void vector<Point> toPoints(const Point& center, const Point& start, const Point& end, const bool& cw, const int& ptCnts)
{
    
    std::vector<sPoint> vPts;
    // 起点,圆心,终点
    float radius = getLength(center, start);
    float startAngle = getAngle(center, start);
    float sweepAngle = 0.0f;
    calcArcAngle(center, start, end, cw, sweepAngle)

    sPoint ptCur = start;
    vPts.push_back(ptCur);
    for (int i = 1; i < ptCnts; i++)
    {
    
        ptCur.x = center.x + radius * cos(startAngle + (cw ? -1 : 1) * (sweepAngle * i / count));
        ptCur.y = center.y + radius * sin(startAngle + (cw ? -1 : 1) * (sweepAngle * i / count));
        vPts.push_back(ptCur);
    }
    ptCur = end;
    vPts.push_back(ptCur);

    return vPts;
}

解析实现效果

在这里插入图片描述

最后

感谢各位大佬的无私奉献。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yoyo18520/article/details/135351162

智能推荐

JWT(Json Web Token)实现无状态登录_无状态token登录-程序员宅基地

文章浏览阅读685次。1.1.什么是有状态?有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session。例如登录:用户登录后,我们把登录者的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session。然后下次请求,用户携带cookie值来,我们就能识别到对应session,从而找到用户的信息。缺点是什么?服务端保存大量数据,增加服务端压力 服务端保存用户状态,无法进行水平扩展 客户端请求依赖服务.._无状态token登录

SDUT OJ逆置正整数-程序员宅基地

文章浏览阅读293次。SDUT OnlineJudge#include<iostream>using namespace std;int main(){int a,b,c,d;cin>>a;b=a%10;c=a/10%10;d=a/100%10;int key[3];key[0]=b;key[1]=c;key[2]=d;for(int i = 0;i<3;i++){ if(key[i]!=0) { cout<<key[i.

年终奖盲区_年终奖盲区表-程序员宅基地

文章浏览阅读2.2k次。年终奖采用的平均每月的收入来评定缴税级数的,速算扣除数也按照月份计算出来,但是最终减去的也是一个月的速算扣除数。为什么这么做呢,这样的收的税更多啊,年终也是一个月的收入,凭什么减去12*速算扣除数了?这个霸道(不要脸)的说法,我们只能合理避免的这些跨级的区域了,那具体是那些区域呢?可以参考下面的表格:年终奖一列标红的一对便是盲区的上下线,发放年终奖的数额一定一定要避免这个区域,不然公司多花了钱..._年终奖盲区表

matlab 提取struct结构体中某个字段所有变量的值_matlab读取struct类型数据中的值-程序员宅基地

文章浏览阅读7.5k次,点赞5次,收藏19次。matlab结构体struct字段变量值提取_matlab读取struct类型数据中的值

Android fragment的用法_android reader fragment-程序员宅基地

文章浏览阅读4.8k次。1,什么情况下使用fragment通常用来作为一个activity的用户界面的一部分例如, 一个新闻应用可以在屏幕左侧使用一个fragment来展示一个文章的列表,然后在屏幕右侧使用另一个fragment来展示一篇文章 – 2个fragment并排显示在相同的一个activity中,并且每一个fragment拥有它自己的一套生命周期回调方法,并且处理它们自己的用户输_android reader fragment

FFT of waveIn audio signals-程序员宅基地

文章浏览阅读2.8k次。FFT of waveIn audio signalsBy Aqiruse An article on using the Fast Fourier Transform on audio signals. IntroductionThe Fast Fourier Transform (FFT) allows users to view the spectrum content of _fft of wavein audio signals

随便推点

Awesome Mac:收集的非常全面好用的Mac应用程序、软件以及工具_awesomemac-程序员宅基地

文章浏览阅读5.9k次。https://jaywcjlove.github.io/awesome-mac/ 这个仓库主要是收集非常好用的Mac应用程序、软件以及工具,主要面向开发者和设计师。有这个想法是因为我最近发了一篇较为火爆的涨粉儿微信公众号文章《工具武装的前端开发工程师》,于是建了这么一个仓库,持续更新作为补充,搜集更多好用的软件工具。请Star、Pull Request或者使劲搓它 issu_awesomemac

java前端技术---jquery基础详解_简介java中jquery技术-程序员宅基地

文章浏览阅读616次。一.jquery简介 jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互 jQuery 的功能概括1、html 的元素选取2、html的元素操作3、html dom遍历和修改4、js特效和动画效果5、css操作6、html事件操作7、ajax_简介java中jquery技术

Ant Design Table换滚动条的样式_ant design ::-webkit-scrollbar-corner-程序员宅基地

文章浏览阅读1.6w次,点赞5次,收藏19次。我修改的是表格的固定列滚动而产生的滚动条引用Table的组件的css文件中加入下面的样式:.ant-table-body{ &amp;amp;::-webkit-scrollbar { height: 5px; } &amp;amp;::-webkit-scrollbar-thumb { border-radius: 5px; -webkit-box..._ant design ::-webkit-scrollbar-corner

javaWeb毕设分享 健身俱乐部会员管理系统【源码+论文】-程序员宅基地

文章浏览阅读269次。基于JSP的健身俱乐部会员管理系统项目分享:见文末!

论文开题报告怎么写?_开题报告研究难点-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏15次。同学们,是不是又到了一年一度写开题报告的时候呀?是不是还在为不知道论文的开题报告怎么写而苦恼?Take it easy!我带着倾尽我所有开题报告写作经验总结出来的最强保姆级开题报告解说来啦,一定让你脱胎换骨,顺利拿下开题报告这个高塔,你确定还不赶快点赞收藏学起来吗?_开题报告研究难点

原生JS 与 VUE获取父级、子级、兄弟节点的方法 及一些DOM对象的获取_获取子节点的路径 vue-程序员宅基地

文章浏览阅读6k次,点赞4次,收藏17次。原生先获取对象var a = document.getElementById("dom");vue先添加ref <div class="" ref="divBox">获取对象let a = this.$refs.divBox获取父、子、兄弟节点方法var b = a.childNodes; 获取a的全部子节点 var c = a.parentNode; 获取a的父节点var d = a.nextSbiling; 获取a的下一个兄弟节点 var e = a.previ_获取子节点的路径 vue