3次Bezier曲线求交

算法描述:
将文件中点的坐标代入到三次Bezier曲线表达式,给定步长,在两条曲线上各取n个点,分别计算各点距离,若距离小于给定的精度值d_p则认为相交,若两个交点的x距离小于给定的精度值x_p则认为是一个点,不重复计入。

#求两个3次Bezier 曲线的交点
def Readf():#读取文件
    ls = []
    ls1 = []
    ls2 = []
    ls = open("Bezier.txt").readlines()
    ls[0] = ls[0].strip('\n').split(',')
    ls[1] = ls[1].split(',')
    for i in range(0,4):
        ls1.append((eval(ls[0][2*i]), eval(ls[0][2*i+1])))
        ls2.append((eval(ls[1][2*i]), eval(ls[1][2*i+1])))
    return ls1, ls2

def Curve(p1, p2, p3, p4):#计算曲线
    p = []
    t_p = 100#划分精度
    for i in range(0, t_p):
        t = i/t_p
        x = pow(1-t,3)*p1[0]+3*t*pow(1-t,2)*p2[0]+3*pow(t,2)*(1-t)*p3[0]+pow(t,3)*p4[0]
        y = pow(1-t,3)*p1[1]+3*t*pow(1-t,2)*p2[1]+3*pow(t,2)*(1-t)*p3[1]+pow(t,3)*p4[1]
        p.append((x,y))
    return p

def Distance(p1, p2):#计算距离
    d = pow(p1[0]-p2[0],2) + pow(p1[1]-p2[1],2)
    d = pow(d,0.5)
    return d

d_p = 0.03#两条曲线上的点距小于d_p认为相交
x_p = 0.0001#同一条曲线上的x距离小于x_p则认为是一个点
ps = []
ps1, ps2 = Readf()#读取坐标
bz1 = Curve(ps1[0],ps1[1],ps1[2],ps1[3])#第一条曲线
bz2 = Curve(ps2[0],ps2[1],ps2[2],ps2[3])#第二条曲线
dmin = Distance(bz1[0], bz2[0])
for i in range(len(bz1)):
    for j in range(len(bz2)):
        d = Distance(bz1[i], bz2[j])#计算各点之间距离
        if d < dmin:
            dmin = d
            if dmin < d_p:
                dmin = d_p
                for p in ps:
                    if abs(p[0]-bz1[i][0]) < x_p:
                        break
                else:
                    ps.append(bz1[i])
                    print("交点坐标({:.2f},{:.2f})".format(bz1[i][0], bz1[i][1]))
if len(ps) == 0:
print("无交点,最小间距{:.2f}".format(dmin))

测试案例:

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
从2阶到7阶的贝赛尔曲线 private static final int MAX_COUNT = 7; // 贝塞尔曲线最大阶数 private static final int REGION_WIDTH = 30; // 合法区域宽度 private static final int FINGER_RECT_SIZE = 60; // 矩形尺寸 private static final int BEZIER_WIDTH = 10; // 贝塞尔曲线线宽 private static final int TANGENT_WIDTH = 6; // 切线线宽 private static final int CONTROL_WIDTH = 12; // 控制点连线线宽 private static final int CONTROL_RADIUS = 12; // 控制点半径 private static final int TEXT_SIZE = 40; // 文字画笔尺寸 private static final int TEXT_HEIGHT = 60; // 文本高度 private static final int RATE = 10; // 移动速率 private static final int HANDLER_WHAT = 100; private static final int FRAME = 1000; // 1000帧 private static final String[] TANGENT_COLORS = {"#7fff00", "#7a67ee", "#ee82ee", "#ffd700", "#1c86ee", "#8b8b00"}; // 切线颜色 private static final int STATE_READY = 0x0001; private static final int STATE_RUNNING = 0x0002; private static final int STATE_STOP = 0x0004; private static final int STATE_TOUCH = 0x0010; private Path mBezierPath = null; // 贝塞尔曲线路径 private Paint mBezierPaint = null; // 贝塞尔曲线画笔 private Paint mMovingPaint = null; // 移动点画笔 private Paint mControlPaint = null; // 控制点画笔 private Paint mTangentPaint = null; // 切线画笔 private Paint mLinePaint = null; // 固定线画笔 private Paint mTextPointPaint = null; // 点画笔 private Paint mTextPaint = null; // 文字画笔 private ArrayList mBezierPoints = null; // 贝塞尔曲线点集 private PointF mBezierPoint = null; // 贝塞尔曲线移动点 private ArrayList mControlPoints = null; // 控制点集 private ArrayList<ArrayList<ArrayList>> mTangentPoints; // 切线点集 private ArrayList<ArrayList> mInstantTangentPoints; private int mR = 0; // 移动速率 private int mRate = RATE; // 速率 private int mState; // 状态 private boolean mLoop = false; // 设置是否循环 private boolean mTangent = true; // 设置是否显示切线 private int mWidth = 0, mHe
### 回答1: Bezier曲线的插值算法优点是: 1. 简单易懂:Bezier曲线的插值算法相对于其他插值算法来说比较简单,易于理解和实现。 2. 控制点灵活:Bezier曲线的控制点可以自由调整,可以通过调整控制点的位置、数量和权重等参数,实现不同形状和曲率的曲线。 3. 高精度:Bezier曲线的插值精度较高,可以通过增加控制点的数量来提高精度。此外,Bezier曲线还具有良好的光滑性和连续性,不会产生锯齿状的效果。 4. 适用范围广:Bezier曲线的插值算法适用于二维和三维曲线的绘制、动画、CAD、计算机游戏等领域。 Bezier曲线的插值算法缺点是: 1. 不能保证曲线经过所有点:Bezier曲线的插值算法不能保证曲线经过所有给定的点,只能保证曲线在控制点之间运动。 2. 大量控制点会导致运算量增加:当需要绘制复杂的曲线时,需要增加控制点的数量,这样会导致计算量增加,影响程序的运行速度。 3. 需要调整控制点才能实现所需形状:Bezier曲线的插值需要通过调整控制点才能实现所需的形状,这可能需要一些经验和技巧。 4. 对于高Bezier曲线,存在振荡和拐角问题:对于高Bezier曲线,存在振荡和拐角问题,需要进行特殊处理,否则会影响曲线的光滑度和连续性。 ### 回答2: 基于Bezier曲线的插值算法是一种常用的图形插值方法,它通过控制点来定义曲线的形状。其优点主要体现在以下几个方面: 1. 简单易懂:Bezier曲线的计算公式简单明了,容易理解和掌握。通过调整控制点的位置,可以快速实现对曲线形状的调整。 2. 光滑性好:Bezier曲线具有光滑的特性,能够在相邻曲线段之间实现平滑的连接。这使得通过Bezier曲线进行插值时,曲线在变化过程中能够保持连续和平滑,避免了锯齿状的变形。 3. 精度可控:通过增加Bezier曲线的阶数,可以提高曲线的插值精度。在需要高精度插值的情况下,可以通过增加控制点的数量来精确地定义曲线形状。 然而,基于Bezier曲线的插值算法也存在一些缺点: 1. 局限性:Bezier曲线只能用于插值控制点之间的曲线,无法应用于非均匀或非连续的数据点插值。这限制了Bezier曲线在某些数据处理场景的应用。 2. 受控制点位置的影响较大:Bezier曲线的形状由控制点的位置和数量决定,而且对控制点的位置敏感。若控制点设置不合理,可能会导致曲线出现奇异形状。 3. 难以精确插值:与一些其他插值方法相比,基于Bezier曲线的插值算法在实现精确的数据点插值时需要增加较多的控制点,从而增加了计算复杂度。 综上所述,基于Bezier曲线的插值算法具有简易、光滑性好和可控精度等优点,但同时也存在局限性、对控制点位置敏感和难以精确插值等缺点。在具体应用时,要根据实际需和数据特点来选择合适的插值算法。 ### 回答3: 基于Bezier曲线的插值算法优缺点如下: 优点: 1. 算法简单:Bezier曲线的插值算法易于实现,通过简单的计算可以得到平滑的曲线。 2. 控制点可调整:通过调整Bezier曲线的控制点,可以实现对生成曲线的形状进行灵活的调整,使得曲线更加符合设计需。 3. 可实现局部调整:对于曲线上的某个局部区域,只需调整相应的控制点,即可改变该区域的形状,不影响其他区域。 缺点: 1. 插值误差:Bezier曲线的插值算法在某些情况下可能会有一定的插值误差,即生成的曲线与原始数据之间存在微小的差异。 2. 可视性处理困难:当多个Bezier曲线进行插值时,可能会出现曲线之间的交叉或重叠现象,处理这些情况相对困难,需要进行额外的处理。 3. 边界条件处理:对于曲线的端点,由于缺少额外的信息限制,生成的曲线可能会超出原始数据的范围,需要进行额外的处理来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值