Thanks for the nice code.
I wrote a quick python version (not thoroughly tested):
Nicolas
# 
# Copyright (C) 2011 Nicolas P. Rougier
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the glumpy Development Team nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# 
#
# Better antialias lines in OpenGL adapted from code by Chris Tsang:
#
# http://artgrammer.blogspot.com/2011/05/drawingnearlyperfect2dlinesegments.html
# http://www.codeproject.com/KB/openGL/gllinedraw.aspx
#
# 
def line( start, end, thickness, color):
'''
Draw a line from P1 to P2
** Parameters **
start : (float,float)
Start point
end : (float,float)
End point
thickness :
Line thickness
color : (float,float,float)
Line color as a normalized (r,g,b) tuple
'''
f = thickness  int(thickness)
alpha = 1.0
x1,y1 = start
x2,y2 = end
r, g, b = color
# Determine parameters t and R
if 0 <= thickness < 1.0:
t = 0.050
R = 0.480 + f*0.320
alpha = alpha*f
elif 1.0 <= thickness < 2.0:
t = 0.050 + f*0.330
R = 0.768 + f*0.312
elif 2.0 <= thickness < 3.0:
t = 0.380 + f*0.58
R = 1.080
elif 3.0 <= thickness < 4.0:
t = 0.960 + f*0.48
R = 1.080
elif 4.0 <= thickness < 5.0:
t = 1.440 + f*0.46
R = 1.080
elif 5.0 <= thickness < 6.0:
t = 1.900 + f*0.6
R = 1.080
else:
t = 2.500+f*0.50
R = 1.080
# Determine angle of the line (relative to horizonta)
tx = ty = 0
Rx = Ry = 0
cx = cy = 0
tolerance = 0.01
dx = float(end[0]start[0])
dy = float(end[1]start[1])
if abs(dx) < tolerance:
tx = t
ty = 0
Rx = R
Ry = 0
if 0.0 < thickness <= 1.0:
tx = 0.5
Rx = 0.0
elif abs(dy) < tolerance:
tx = t
ty = 0
Rx = R
Ry = 0
if 0.0 < thickness <= 1.0:
tx = 0.5
Rx = 0.0
else:
if (thickness < 3):
m = dy/dx
if m > 0.4142 and m <= 0.4142:
# 22.5< angle <= 22.5, approximate to 0 (degree)
tx = t*0.1
ty = t
Rx = R*0.6
Ry = R
elif m > 0.4142 and m <= 2.4142:
# 22.5< angle <= 67.5, approximate to 45 (degree)
tx = t*0.7071
ty = t*+0.7071
Rx = R*0.7071
Ry = R*+0.7071
elif m > 2.4142 or m<=2.4142:
# 67.5 < angle <=112.5, approximate to 90 (degree)
tx = t
ty = t*0.1
Rx = R
Ry = R*0.6
elif m > 2.4142 and m < 0.4142:
# 112.5 < angle < 157.5, approximate to 135 (degree)
tx = t*0.7071
ty = t*0.7071
Rx = R*0.7071
Ry = R*0.7071
else:
print "Error in determining angle: m=%.4f",m
else:
dx = y1y2
dy = x2x1
L = math.sqrt(dx*dx + dy*dy)
dx /= L
dy /= L
cx = dy
cy = +dx
tx = t*dx
ty = t*dy
Rx = R*dx
Ry = R*dy
x1 += cx*0.5
y1 += cy*0.5
x2 = cx*0.5
y2 = cy*0.5
vertices = [
x1txRxcx, y1tyRycy, # fading edge1
x2txRx+cx, y2tyRy+cy,
x1txcx, y1tycy, # core
x2tx+cx, y2ty+cy,
x1+txcx, y1+tycy,
x2+tx+cx, y2+ty+cy,
x1+tx+Rxcx, y1+ty+Rycy, # fading edge2
x2+tx+Rx+cx, y2+ty+Ry+cy ]
gl.glVertexPointer(2, gl.GL_FLOAT, 0, vertices)
colors = [
r, g, b, 0,
r, g, b, 0,
r, g, b, alpha,
r, g, b, alpha,
r, g, b, alpha,
r, g, b, alpha,
r, g, b, 0,
r, g, b, 0 ]
gl.glColorPointer(4, gl.GL_FLOAT, 0, colors)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 8)
# Line caps
if thickness < 3:
return
vertices = [
x1txRxcx, y1tyRycy, # cap1
x1txRx, y1tyRy,
x1txcx, y1tycy,
x1+tx+Rx, y1+ty+Ry,
x1+txcx, y1+tycy,
x1+tx+Rxcx, y1+ty+Rycy,
x2txRx+cx, y2tyRy+cy, # cap2
x2txRx, y2tyRy,
x2tx+cx, y2ty+cy,
x2+tx+Rx, y2+ty+Ry,
x2+tx+cx, y2+ty+cy,
x2+tx+Rx+cx, y2+ty+Ry+cy ]
gl.glVertexPointer(2, gl.GL_FLOAT, 0, vertices)
colors = [
r, g, b, 0, # cap1
r, g, b, 0,
r, g, b, alpha,
r, g, b, 0,
r, g, b, alpha,
r, g, b, 0,
r, g, b, 0, # cap2
r, g, b, 0,
r, g, b, alpha,
r, g, b, 0,
r, g, b, alpha,
r, g, b, 0 ]
gl.glColorPointer(4, gl.GL_FLOAT, 0, colors)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 6)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 6, 6)
if __name__ == '__main__':
import sys
import math
import OpenGL.GL as gl
import OpenGL.GLUT as glut
def display():
gl.glClear (gl.GL_COLOR_BUFFER_BIT  gl.GL_DEPTH_BUFFER_BIT)
x,y,w,h = gl.glGetIntegerv(gl.GL_VIEWPORT)
gl.glEnable(gl.GL_BLEND);
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
gl.glEnableClientState(gl.GL_COLOR_ARRAY);
start,end = [20,25], [50, 175]
for i in range(1,21):
line(start, end, color = (0,0,0), thickness = i*.3)
start[0] += 30
end[0] += 30
gl.glDisableClientState(gl.GL_VERTEX_ARRAY);
gl.glDisableClientState(gl.GL_COLOR_ARRAY);
glut.glutSwapBuffers()
def resize(width,height):
gl.glViewport(0, 0, width, height+4)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
gl.glOrtho(0, width, 0, height+4, 1, 1)
gl.glMatrixMode(gl.GL_MODELVIEW)
glut.glutInit(sys.argv)
glut.glutInitDisplayMode(glut.GLUT_DOUBLE 
glut.GLUT_RGBA 
glut.GLUT_DEPTH)
glut.glutCreateWindow('GL lines')
glut.glutDisplayFunc(display)
glut.glutReshapeFunc(resize)
glut.glutReshapeWindow(650,200)
gl.glClearColor(1,1,1,1)
glut.glutMainLoop()
modified on Tuesday, July 5, 2011 1:55 PM
