精华内容
下载资源
问答
  • 任意在界面上画一条有连续的多段线,根据左右两侧指定的缓冲距分别在多段线的两侧绘制平行线……
  • 编写个Applet,画出20水平的、随机颜色的平行线。要求线的长度相同,整条线段都要在可视区域内。 ` package p2; import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt...

    编写一个Applet,画出20条水平的、随机颜色的平行线。要求线的长度相同,整条线段都要在可视区域内。
    `
    package p2;

    import java.applet.Applet;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.HeadlessException;
    import java.util.HashSet;
    import java.util.Random;
    import java.util.Set;

    public class DrawLine1 extends Applet
    {

    public DrawLine1() throws HeadlessException
    {
    	super();
    	// TODO Auto-generated constructor stub
    }
    
    public void paint(Graphics g)
    {
    	Random random=new Random();
    	
    	int width=g.getClipBounds().width;//宽度
    	int length=random.nextInt(width);//线的长度,要小于width
    	
    	/***获取20个不同起点的纵坐标***/
    	Set<Integer>set=new HashSet<Integer>();
    	while(set.size()<20)
    	{
    		set.add(random.nextInt(g.getClipBounds().height));
    	}
    	
    	
    	/***画线****/
    	for(Integer startPy:set)
    	{
    		//获取横坐标,要小于(width-height),保证不出界
    		int startPx=random.nextInt(width-length);
    		g.setColor(new Color
    展开全文
  • 不管多短的一条线段,都包含实数集上的无数个点,计算机能的是尽可能多地采样,描更多的点,让人眼难以看出其中的不连续性。已知 x,yx,y 分别为坐标轴上的两点,下式为采样公式, x′=(1−p)⋅x+p⋅y,p∈[0,1] x'...

    计算机能画一条线段(数学意义上)吗?并不能。不管多短的一条线段,都包含实数集上的无数个点,计算机能做的是尽可能多地采样,描更多的点,让人眼难以看出其中的不连续性。

    已知 x,y 分别为坐标轴上的两点,下式为采样公式,

    x=(1p)x+py,p[0,1]

    p 在整个 [0,1]闭区间上取值,可得到介于端点 x,y 之间的值,因为向量 (xx)=p(yx) 平行于向量 yx ,又因为二者共享同一端点 x ,故三者共线。

    import numpy as np
    import matplotlib.pyplot as plt
    
    def main():
        x0, x1 = [1, 1], [2, 2]
        for p in np.linspace(0, 1, 1000):
            plt.plot((1-p)*x0[0]+p*x1[0], (1-p)*x0[1]+p*x1[1], '.', c='k')
        plt.plot(x0[0], x0[1], 'o', ms=10)
        plt.plot(x1[0], x1[1], 'o', ms=10)
        plt.show()
    if __name__ == '__main__':
        main()



    我们不妨对该公式做一次简单推导,如图所示:


    这里写图片描述

    x⃗ z⃗  z⃗ y⃗  共线,不妨令

    x⃗ z⃗ =k(z⃗ y⃗ )x⃗ +ky⃗ =(1+k)z⃗ z⃗ =11+kx⃗ +k1+ky⃗ 11+kλ,11+k1z⃗ =λx⃗ +(1λ)y⃗ 

    展开全文
  • 、设置线宽度、 二、绘制单条线段 GL_LINES、 三、绘制多条线段 GL_LINES、 四、绘制依次连接的点组成的线 GL_LINE_STRIP、 五、绘制圈 GL_LINE_LOOP ( 偶数个点 )、 六、绘制圈 GL_LINE_LOOP ( 奇数个点 )、 七、...





    一、设置线宽度



    线的绘制宽度是 OpenGL 状态机中的一个值 , 通过 glLineWidth 方法设置 ; 下面的代码将线的宽度设置为 2 像素 ;

    		// 设置线的宽度 
    		glLineWidth(2.0f);
    




    二、绘制单条线段 GL_LINES



    绘制线时, 会将从 glBeginglEnd 之间的所有的点都绘制出来 ;

    可以调用 glVertex3f 方法设置成对的点 , 每两个点代表一条线 ;

    注意必须成对设置 , 如果设置 奇数个点 , 最后一个点会被丢弃 ;


    绘制线段时 , glBegin(GL_LINES) 方法传入的参数是 GL_LINES ;

    在 glBegin(GL_LINES) 和 glEnd() 之间设置的点 , 会被自动当做线的两个端点 ;

    如在上述 glBegin 和 glEnd 两个方法之间调用了

            glVertex3f(0.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, 0.0f, -10.0f);
    

    代码 , 含义是绘制一条线段 , 端点分别是 (0,0,-10) 和 (-5,0,-10) ;


    代码示例 :

    		// 渲染场景
    
    		// 清除缓冲区 , 
    		// 使用之前设置的 glClearColor(1.0, 0.0, 0.0, 1.0) 擦除颜色缓冲区
    		// 红色背景
    		glClear(GL_COLOR_BUFFER_BIT);
    
            // 设置当前的绘制颜色 , 4 个 unsigned byte 
            // 每个颜色的分量占一个字节
            // 参数数据是 R 红色 G 绿色 B 蓝色 A 透明度
            // 下面设置的含义是白色, 绘制点的时候, 每次都使用白色绘制
            glColor4ub(255, 255, 255, 255);
    
    		// 设置线的宽度 
    		glLineWidth(2.0f);
    
            // 绘制线时, 会将从 glBegin 到 glEnd 之间的所有的点都绘制出来
            // 可以调用 glVertex3f 方法 成对 设置多条线
    		// 注意必须成对设置 , 如果设置奇数个点 , 最后一个点会被丢弃
            // 绘制线段开始
            glBegin(GL_LINES);
    
            // 绘制线 , 每两个点组成一条线
    		// glVertex3f (GLfloat x, GLfloat y, GLfloat z)
            glVertex3f(0.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, 0.0f, -10.0f);
    
    		// 上面的设置会从 (0,0,-10) 坐标向 (-5,0,-10) 坐标绘制一条线
    
            // 绘制点结束
            glEnd();
    
    		// 将后缓冲区绘制到前台
    		SwapBuffers(dc);
    

    绘制效果 :

    在这里插入图片描述


    注意 : 设置的点个数必须是偶数的 , 如果设置奇数个点 , 最后一个点会被舍弃 ;





    三、绘制多条线段 GL_LINES



    绘制线段时 , glBegin(GL_LINES) 方法传入的参数是 GL_LINES ;

    在 glBegin(GL_LINES) 和 glEnd() 之间设置的点 , 会被自动当做线的两个端点 , 如果设置 4 个点 , OpenGL 会按照顺序 , 从上到下 , 两两组合成一条线段 ;

    如在上述 glBegin 和 glEnd 两个方法之间调用了

            glVertex3f(0.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, 0.0f, -10.0f);
            
            glVertex3f(-5.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, -2.0f, -10.0f);
    

    代码 , 含义是 绘制 2 条线段 , 线段 1 端点分别是 (0,0,-10) 和 (-5,0,-10) , 线段 2 端点分别是 (-5,0,-10) 和 (-5, -2, -10) ;

    		// 渲染场景
    
    		// 清除缓冲区 , 
    		// 使用之前设置的 glClearColor(1.0, 0.0, 0.0, 1.0) 擦除颜色缓冲区
    		// 红色背景
    		glClear(GL_COLOR_BUFFER_BIT);
    
            // 设置当前的绘制颜色 , 4 个 unsigned byte 
            // 每个颜色的分量占一个字节
            // 参数数据是 R 红色 G 绿色 B 蓝色 A 透明度
            // 下面设置的含义是白色, 绘制点的时候, 每次都使用白色绘制
            glColor4ub(255, 255, 255, 255);
    
    		// 设置线的宽度 
    		glLineWidth(2.0f);
    
            // 绘制线时, 会将从 glBegin 到 glEnd 之间的所有的点都绘制出来
            // 可以调用 glVertex3f 方法 成对 设置多条线
    		// 注意必须成对设置 , 如果设置奇数个点 , 最后一个点会被丢弃
            // 绘制线段开始
            glBegin(GL_LINES);
    
            // 绘制线 , 每两个点组成一条线
    		// glVertex3f (GLfloat x, GLfloat y, GLfloat z)
            glVertex3f(0.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, 0.0f, -10.0f);
    
    		// 上面的设置会从 (0,0,-10) 坐标向 (-5,0,-10) 坐标绘制一条线
    
            glVertex3f(-5.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, -2.0f, -10.0f);
            
    		// 上面的设置会从 (-5,0,-10) 坐标向 (-5,-2,-10) 坐标绘制一条线
    
            // 绘制点结束
            glEnd();
    
    		// 将后缓冲区绘制到前台
    		SwapBuffers(dc);
    

    绘制效果 :

    在这里插入图片描述





    四、绘制依次连接的点组成的线 GL_LINE_STRIP



    给 glBegin 传入 GL_LINE_STRIP 参数 , 其作用是绘制各个点依次连接的线 , 但是首尾不连接 ;

    这里注意与 GL_LINE_LOOP 区别 , GL_LINE_LOOP 设置后 , 在 GL_LINE_STRIP 基础上 , 还要进行首尾连接 ;

    代码示例 :

    		// 渲染场景
    
    		// 清除缓冲区 , 
    		// 使用之前设置的 glClearColor(1.0, 0.0, 0.0, 1.0) 擦除颜色缓冲区
    		// 红色背景
    		glClear(GL_COLOR_BUFFER_BIT);
    
            // 设置当前的绘制颜色 , 4 个 unsigned byte 
            // 每个颜色的分量占一个字节
            // 参数数据是 R 红色 G 绿色 B 蓝色 A 透明度
            // 下面设置的含义是白色, 绘制点的时候, 每次都使用白色绘制
            glColor4ub(255, 255, 255, 255);
    
    		// 设置线的宽度 
    		glLineWidth(2.0f);
    
            // 绘制线时, 会将从 glBegin 到 glEnd 之间的所有的点都绘制出来
            // 可以调用 glVertex3f 方法 成对 设置多条线
    		// 注意必须成对设置 , 如果设置奇数个点 , 最后一个点会被丢弃
            // 绘制线段开始
            //glBegin(GL_LINES);
            //glBegin(GL_LINE_LOOP);
            glBegin(GL_LINE_STRIP);
    
            // 绘制线 , 每两个点组成一条线
    		// glVertex3f (GLfloat x, GLfloat y, GLfloat z)
            glVertex3f(0.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, 0.0f, -10.0f);
    
    		// 上面的设置会从 (0,0,-10) 坐标向 (-5,0,-10) 坐标绘制一条线
    
            glVertex3f(-5.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, -2.0f, -10.0f);
    
    		// 上面的设置会从 (-5,0,-10) 坐标向 (-5,-2,-10) 坐标绘制一条线
    
            // 绘制点结束
            glEnd();
    
    		// 将后缓冲区绘制到前台
    		SwapBuffers(dc);
    

    效果展示 :

    在这里插入图片描述





    五、绘制圈 GL_LINE_LOOP ( 偶数个点 )



    绘制圈时 , 在 glBegin 中传入 GL_LINE_LOOP 参数 , 绘制时会将 glBegin 和 glEnd 之间的点连线 , 并且最后一个点会和第一个点连在一起 , 组成一个圈 ;

    代码示例 : 下面的代码与 三 中的代码区别是 , glBegin 中传入的参数是 GL_LINE_LOOP , 不再传入 GL_LINES 参数 ;

    		// 渲染场景
    
    		// 清除缓冲区 , 
    		// 使用之前设置的 glClearColor(1.0, 0.0, 0.0, 1.0) 擦除颜色缓冲区
    		// 红色背景
    		glClear(GL_COLOR_BUFFER_BIT);
    
            // 设置当前的绘制颜色 , 4 个 unsigned byte 
            // 每个颜色的分量占一个字节
            // 参数数据是 R 红色 G 绿色 B 蓝色 A 透明度
            // 下面设置的含义是白色, 绘制点的时候, 每次都使用白色绘制
            glColor4ub(255, 255, 255, 255);
    
    		// 设置线的宽度 
    		glLineWidth(2.0f);
    
            // 绘制线时, 会将从 glBegin 到 glEnd 之间的所有的点都绘制出来
            // 可以调用 glVertex3f 方法 成对 设置多条线
    		// 注意必须成对设置 , 如果设置奇数个点 , 最后一个点会被丢弃
            // 绘制线段开始
            //glBegin(GL_LINES);
            glBegin(GL_LINE_LOOP);
    
            // 绘制线 , 每两个点组成一条线
    		// glVertex3f (GLfloat x, GLfloat y, GLfloat z)
            glVertex3f(0.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, 0.0f, -10.0f);
    
    		// 上面的设置会从 (0,0,-10) 坐标向 (-5,0,-10) 坐标绘制一条线
    
            glVertex3f(-5.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, -2.0f, -10.0f);
    
    		// 上面的设置会从 (-5,0,-10) 坐标向 (-5,-2,-10) 坐标绘制一条线
    
            // 绘制点结束
            glEnd();
    
    		// 将后缓冲区绘制到前台
    		SwapBuffers(dc);
    

    绘制效果 : 最后一个点与第一个点连成线段 , 组成一个闭合的三角形 ;

    在这里插入图片描述





    六、绘制圈 GL_LINE_LOOP ( 奇数个点 )



    绘制圈时 , 如果设置奇数个点 , 最后一个点也会进行连线 , 如上面的四个点 , 去掉第三个点 , 也可以画出一模一样的图形 ;

    		// 渲染场景
    
    		// 清除缓冲区 , 
    		// 使用之前设置的 glClearColor(1.0, 0.0, 0.0, 1.0) 擦除颜色缓冲区
    		// 红色背景
    		glClear(GL_COLOR_BUFFER_BIT);
    
            // 设置当前的绘制颜色 , 4 个 unsigned byte 
            // 每个颜色的分量占一个字节
            // 参数数据是 R 红色 G 绿色 B 蓝色 A 透明度
            // 下面设置的含义是白色, 绘制点的时候, 每次都使用白色绘制
            glColor4ub(255, 255, 255, 255);
    
    		// 设置线的宽度 
    		glLineWidth(2.0f);
    
            // 绘制线时, 会将从 glBegin 到 glEnd 之间的所有的点都绘制出来
            // 可以调用 glVertex3f 方法 成对 设置多条线
    		// 注意必须成对设置 , 如果设置奇数个点 , 最后一个点会被丢弃
            // 绘制线段开始
            //glBegin(GL_LINES);
            glBegin(GL_LINE_LOOP);
    
            // 绘制线 , 每两个点组成一条线
    		// glVertex3f (GLfloat x, GLfloat y, GLfloat z)
            glVertex3f(0.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, 0.0f, -10.0f);
    
    		// 上面的设置会从 (0,0,-10) 坐标向 (-5,0,-10) 坐标绘制一条线
    
            //glVertex3f(-5.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, -2.0f, -10.0f);
    
    		// 上面的设置会从 (-5,0,-10) 坐标向 (-5,-2,-10) 坐标绘制一条线
    
            // 绘制点结束
            glEnd();
    
    		// 将后缓冲区绘制到前台
    		SwapBuffers(dc);
    

    在这里插入图片描述





    七、绘制彩色的线



    在上面 六 的代码基础上 , 在绘制每个点之前 , 都设置当前的颜色值 , 即 OpenGL 状态机中的当前颜色值 ,

    第一个点 glVertex3f(0.0f, 0.0f, -10.0f) , 绘制前设置的是 白色 ,

    第二个点 glVertex3f(-5.0f, 0.0f, -10.0f) , 绘制前设置的是 绿色 ,

    第三个点 glVertex3f(-5.0f, -2.0f, -10.0f) , 绘制前设置的是 蓝色 ;

    设置颜色就是在点设置前调用 glColor4ub(0, 0, 255, 255) 方法 , 设置当前颜色 ;

    白色的点绿色的点 之间连线时 , 颜色会从白色渐变到绿色 ;

    代码如下 :

    		// 渲染场景
    
    		// 清除缓冲区 , 
    		// 使用之前设置的 glClearColor(1.0, 0.0, 0.0, 1.0) 擦除颜色缓冲区
    		// 红色背景
    		glClear(GL_COLOR_BUFFER_BIT);
    
            // 设置当前的绘制颜色 , 4 个 unsigned byte 
            // 每个颜色的分量占一个字节
            // 参数数据是 R 红色 G 绿色 B 蓝色 A 透明度
            // 下面设置的含义是白色, 绘制点的时候, 每次都使用白色绘制
            glColor4ub(255, 255, 255, 255);
    
    		// 设置线的宽度 
    		glLineWidth(2.0f);
    
            // 绘制线时, 会将从 glBegin 到 glEnd 之间的所有的点都绘制出来
            // 可以调用 glVertex3f 方法 成对 设置多条线
    		// 注意必须成对设置 , 如果设置奇数个点 , 最后一个点会被丢弃
            // 绘制线段开始
            //glBegin(GL_LINES);
    		//glBegin(GL_LINE_STRIP);
            glBegin(GL_LINE_LOOP);
            
            // 绘制线 , 每两个点组成一条线
    		// glVertex3f (GLfloat x, GLfloat y, GLfloat z)
            glVertex3f(0.0f, 0.0f, -10.0f);
    
    		// 设置绿色 
    		glColor4ub(0, 255, 0, 255);
    
            glVertex3f(-5.0f, 0.0f, -10.0f);
    
    		// 上面的设置会从 (0,0,-10) 坐标向 (-5,0,-10) 坐标绘制一条线
    
    		// 设置蓝色
    		glColor4ub(0, 0, 255, 255);
    
            //glVertex3f(-5.0f, 0.0f, -10.0f);
            glVertex3f(-5.0f, -2.0f, -10.0f);
    
    		glColor4ub(255, 255, 255, 255);
    
    		// 上面的设置会从 (-5,0,-10) 坐标向 (-5,-2,-10) 坐标绘制一条线
    
            // 绘制点结束
            glEnd();
    
    		// 将后缓冲区绘制到前台
    		SwapBuffers(dc);
    

    运行效果如下 :

    1 1 1 个点白色 , 第 2 2 2 个点绿色 , 第 3 3 3 个点蓝色 ;

    线段 1 1 1 白色 ~ 绿色渐变 , 线段 2 2 2 绿色 ~ 蓝色渐变 , 线段 3 3 3 蓝色 ~ 白色渐变 , 这是 OpenGL 固定管线差值出来的颜色 ;

    在这里插入图片描述





    八、相关资源



    GitHub 地址 : https://github.com/han1202012/OpenGL

    博客源码快照 : https://download.csdn.net/download/han1202012/14740988

    展开全文
  • N条线段求交的扫描线算法 在对图进行计算时,很常用的个操作就是求若干条线段的交点,比如对图的叠加、截窗,需要频繁地计算线段交点,如果求交算法效率很低,上层的算法再优秀也表现不出好的性能。 先考虑...

    转载自:http://johnhany.net/2013/11/sweep-algorithm-for-segments-intersection/

     

    N条线段求交的扫描线算法

            在对图进行计算时,很常用的一个操作就是求若干条线段的交点,比如对图的叠加、截窗,需要频繁地计算线段交点,如果求交算法效率很低,上层的算法再优秀也表现不出好的性能。


            先考虑一个很简单的情形:只有两条线段,求它们是否相交,如果相交,交点在哪?

                                                   

        如左图,如果线段[a0,a1]与[b0,b1]相交,则端点a0、a1必定落在[b0,b1]两侧,同时端点b0、b1必定落在[a0,a1]两侧。只要这两个条件同时满足,即认为两线段相交。(一条线段的端点落在另一条线段上也认为是两线段相交)

        一种比较快速的方法是使用向量外积。

        三角形面积公式的向量形式为:

              triangle_area

            面积恰是两边a,b外积大小的一半。而外积是有方向的。判断两点是否同侧,只需要判断外积是否同号。比如对上面的图进行如下计算:

            s1=(xb0-xa0)*(yb1-ya0)-(xb1-xa0)*(yb0-ya0)

            s2=(xb0-xa1)*(yb1-ya1)-(xb1-xa1)*(yb0-ya1)

            其中s1方向垂直屏幕向内,s2方向垂直屏幕向外,两者异号,所以点a0、a1位于线段[b0,b1]两侧。

            同理,计算s3=(xa1-xb0)*(ya0-yb0)-(xa0-xb0)*(ya1-yb0)和s4=s2-s1+s3异号,可以确定b0、b1落在[a0,a1]两侧。(由面积恒等关系s4-s3=s2-s1可以直接计算s4)

            确定两条线段相交,接着就要计算交点。这一步没有必要用向量计算,只要求解直角坐标下的方程组就好。不过需要注意端点重合的情况。

     

    //inte[i][0]为交点x坐标
    //inte[i][1]为交点y坐标
    //_inteCount为之前找到的交点总数
    if(xa0==xa1 || xb0==xb1)
    {
        if(xa0==xa1)
        {
            b=(yb0-yb1)/(xb0-xb1);
            inte[_inteCount][0]=xa0;
            inte[_inteCount][1]=b*(inte[_inteCount][0]-xb1)+yb1;
        }
        else
        {
            a=(ya0-ya1)/(xa0-xa1);
            inte[_inteCount][0]=xb0;
            inte[_inteCount][1]=a*(inte[_inteCount][0]-xa1)+ya1;
        }
    }
    else
    {
        a=(ya0-ya1)/(xa0-xa1);
        b=(yb0-yb1)/(xb0-xb1);
        inte[_inteCount][0]=(a*xa1-b*xb1-ya1+yb1)/(a-b);
        inte[_inteCount][1]=a*(inte[_inteCount][0]-xa1)+ya1;
    }

            现在考虑有很多条线段的情形。如果把这N条线段两两检查交点,时间复杂度是O(n^2),在线段数目很多时,计算速度会非常慢。这时,就需要扫描线算法了。

            观察一下那些相交的线段有什么特点。把每条线段向y轴投影:

                                      

     

            可以看出相交的线段的投影会彼此叠加,而且投影不重合的线段也不可能相交。

            利用这个特性,用一条平行的直线从上到下平移,平移的过程中会与某些线段相交,在任何时刻只考虑这些与扫描线相交的线段之间是否相交。现考虑某时刻这条扫描线上的M条线段(M<=N):

                                          

            在这条扫描线上,相交的线段一定是相邻的,比如b和c。虽然存在b和d不相邻也相交的情况,但由于算法的特点,处理到那个交点时,b和d一定是相邻的。比如:

                                                

    扫描线在点T上方时,c与d相邻,但b与d不相邻。找到交点T。但扫描线经过T到达S上方时,c与d的位置交换了,此时b与d相邻而且相交。所以,只有相邻的线段才有可能相交。

            我们把相邻的线段称为互为邻居,比如a是b的左邻居,c是b的右邻居。

            在扫描线行进的过程中,需要动态维护两个数据结构:

                    一条链表,负责记录所以线段的端点和已经找到的交点,每个点按y递减顺序存储(y相同的,按x递增排序);

                    一棵二叉树,负责记录与扫描线相交的线段(确切地说,保存的是每条线段的上端点),每条线段按照上端点的x坐标递增顺序存储。

            所谓“扫描”,即程序从头到尾依次处理链表上的每个点,在每处理一个新的点时,会相应地更新链表和二叉树。新的点共有三种,相应的处理方法如下所述:

            1.新点是某线段的上端点p0:

                    把这个端点存入二叉树,然后在树中找到p0的左邻居pa和右邻居pb,检查p0与pa是否相交,p0与pb是否相交。如果有交点,把交点存入链表。

                               

                    比如b的上端点接触到扫描线,只需要检查a与b是否相交,b与c是否相交。

                    新交点一定会在扫描线的下方,它在链表中的位置也一定在p0的后面,会在未来某个时刻得到处理。因为如果这个交点的位置在p0之前,说明扫描线在之前已经经过了这个交点,程序也已经处理过它了。

            2.新点是某线段的下端点p1:

                    在二叉树内找到p1相应的上端点,然后找到上端点的左邻居pa和右邻居pb。把p0从二叉树删除,检查pa与pb是否相交。如果有交点,把交点存入链表。

                                                     

    比如b的下端点离开扫描线,删除b后检查a与c是否相交。

            3.新点是交点pt:

                    输出这个交点的坐标。然后在二叉树中找到这个交点所在的两条线段pl和pr(假设pl在pr的左边),再找到pl的左邻居pa,和pr的右邻居pb,检查pr与pa是否相交,pl与pb是否相交。如果有交点,把交点存入链表。

                              

                    比如b与c的交点接触到扫描线,检查a与c是否相交,b与d是否相交。

            以上就是扫描线算法的全部细节。采用这种算法,可以把时间复杂度降到O(nlogn+klogn),其中n是线段数目,k是交点数目。如果想了解这个时间是怎样计算出来的,可以参考《Computational Geometry Algorithms and Applications》(作者:M. de Berg, M. van Kreveld, M. Overmars and O. Schwarzkopf)


            我用C实现了这个算法,并且用OpenGL绘制出所有线段及交点。代码可以在这里下载:

                    https://github.com/johnhany/SegmentsIntersection

            这是程序运行的结果:

                                       

     

            这里还有一个扫描线求交算法的在线Java演示:Sweep Line Algorithm for Segment Intersection

    展开全文
  • 在上述博客中,我分别对平滑滤波、边缘检测、直线检测了一定程度的了解,那么最终的目的我们是需要解决实际问题,那么今天就试着完成个简单的综合训练,来在巩固前面所学知识的同时,学到...算出这两平行线之间...
  • 该函数实现了 Vladimir J. LUMELSKY,“线段之间距离的快速计算”,信息处理快报 21 (1985) 55-61... 它也处理所有退化情况(当线平行时,一条线是一个点,两条线都是点)。 或者,该函数可以返回线段上最近的两个点。
  • HPU暑假积分赛平行线 暑假第场积分赛 *实力被捶 * 平常打的比赛很少 看来以后确实需要参加一些网赛 学长出的题真是能够锻炼心态 首先心态真的很重要 人生中第篇博客 写的可能不是很好 请各位DL赐教 题目传送...
  • 【opencv】两条平行线之间的距离

    万次阅读 2014-03-10 23:05:42
    问题:一张输入图片如下,有两条平行线,求出两条平行线之间的距离 解决思路: 1. 对图像中的直线进行细化 2. 提取直线的轮廓坐标 3. 对轮廓上的坐标进行直线集合,从而得到直线方程 4. 计算两直线之间的距离 ...
  • ②在同一平面内,不相交的两条线段平行③过一点有且只有一条直线与已知直线平行; ④若a∥b,b∥c,则a与c不相交.A.1个 B.2个 C.3个 D.4个2、在同一平面内,两条不重合直线的位置关系可能是〔 〕A.平行或相交 B.垂直或...
  • 条线段求交点编程

    千次阅读 2017-05-17 11:29:07
    今天需要验证两条线段是否相交,突然发现两点求一条直线不会了,然后我就自己在草稿上求了一番。 已知两个线段分别是(x1,y1)(x2,y2)以及(x3,y3)(x4,y4),假设这两条线段平行。 设线段所在的直线为ax-by+c=0 ...
  • OpenCV计算两条平行线之间的距离

    千次阅读 2019-04-23 08:25:48
    //二值处理,将图像转换成0,1 //第步 对图像中的直线进行细化 ThinImage(pTmp,pDst,80); #define SHOWRESULT #ifdef SHOWRESULT cvNamedWindow("src",1);//创建窗口 cvNamedWindow("dst",1); ...
  • G. 平行线

    2019-09-20 16:32:52
    为了管理动物园不听话的大猩猩们,动物管理员Boctorio决定去远方的ACM之城找一些平行线,当他逛到个神奇的店铺时,他发现了副黑色的图,上面依稀可见一些白色的点。Boctorio询问店铺老板这幅画是什么,老板说:...
  • 【OpenCV图像处理】激光条纹线段提取、中心线提取

    千次阅读 多人点赞 2019-07-22 21:42:46
    #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <stdio.h> using namespace std;...//----...
  • 个平面上,给出两条线段,判断它们是否有交点。如果有交点,求出这个交点;如果没有,返回null。 我们分析一下,什么情况下两线段才会相交。 首先我们要求出两线段对应的直线的交点。在个平面上,两条不平行...
  • 遥感图像的机场检测是图像处理在军事以及航空领域个重要的应用,现有一些机场提取方法利用显著性特征获取机场区域的方法容易使得机场提取不够完整,而且会混入过多的虚警区域,原因在于图像的显著性特征并能用来...
  • 题意,给你n条线段然后让你判断有几个交点。 所以思路就是判断两条线段是否相交,然后for一下就好了啊 那么怎么判断两条线段相交呢 1.好像普遍用叉积的方法吧【T^T】 叉积:矢量的矢量积 记作a×b,其...
  • 计算二条线段相交

    2015-04-27 21:11:58
    线段A(x1,y1)-B(x2,y2),所在直线L1方程为F(x,y)=0; 线段C(x3,y3)-D(x4,y4),所在直线L2方程为G(x,y)=0; 思路:(即问题的充要条件) (点A与点B在直线L2两侧) AND (点C与点D在直线L1两侧); 方法: 如果点P(Xp,Yp)不...
  • 条线段相交判断学习理解

    千次阅读 2017-12-19 10:10:50
    步检查以线段A为对角线的矩形和以线段B对角线的矩形是否相交,如果不相交则两条线段必然不相交,可以快速排除,如果相交就继续检查是否有交点; 所以第步也叫做快速排斥实验,首先先进行第步的研究:   ...
  • 我通过点击AB两点生成直线,然后通过鼠标移动来得到平行于AB的线?这个moveAB两点怎么计算呢?![图片说明](https://img-ask.csdn.net/upload/201709/27/1506513348_955833.png)
  • cad画两条平行线的中线的方法步骤:cad画两条平行线的中线的方法一1、很简单,在两条平行线之间再“offset”一条平行线,与俩条平行线等距。2、在中间平行线上任一点为圆心,定距离为直径圆,圆与两条平行线的交点...
  • 在同一平面内,不相交的两直线叫平行线.平行线是初中平面几何最基本的,也是非常重要的图形.在证明某些平面几何问题时,若能依据证题的需要,添加恰当的平行线,则能使证明顺畅、简洁.  添加平行线证题,一般有如下四种...
  • 条线段距离

    千次阅读 2012-03-20 19:27:33
    线段间最小距离 时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte 描述 作为程序员的沈同学深深地知道大学所学课程的重要性,没有不重要的课程,当我们不知道如何应用所学知识的时候,我们就会...
  • 这是根据每周练的第周题目要求的。先检测出两平行直线,再计算出其距离。
  • 折线平行线的计算方法

    千次阅读 2017-10-10 07:57:09
    给定个简单多边形,多边形按照顺时针或者逆时针的数许排列 内部等距离缩小或者外部放大的多边形,...平行于L1和L2,平行线间距是L的,并且位于多边形内部的两边,交于Qi 我们要计算出Qi的坐标 如图, P
  • 如何判断两条线段相交

    千次阅读 2011-11-23 00:26:13
    1.矢量的概念:如果一条线段的端点是有次序之分的,我们把这种线段成为有向线段(directed segment)。如果有向线段p1p2的起点p1在坐标原点,我们可以把它称为矢量(vector)p2。 2.矢量加减法:设二维矢量P =
  • 题目就是矩阵面积并这里我就不多说了 这道题的精髓在于运用线段树来求边长,扫描线的思想反而没有线段树重要 ...class node//线段树的结构我们是用一条平行于y轴的线去扫描的 { //也就是说我们这个线
  • 从 B 发出一条(任意一条)与 AB 不重合的射线 BC 任取 BC 上三点 D、E、F,使得 |BD|=|DE|=|EF|(对长度没用任何要求) 连接 FA 过 E AF 的平行线,交AB 于 H 过 D AF(EH)的平行线,交 AB 于 G。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,345
精华内容 3,338
关键字:

做一条线段的平行线