Line width and the orientation of the edges of lines

Hi! I’m trying to create an experiment in which two lines are displayed. One of them is supposed to be horizontal, another angled at 45º away from it, like in the picture attached. I’d like them both to have lineWidth=20.

Ideally, the width of the lines themselves should be 20, and the edges at the two ends of the line should be perpendicular to the orientation of the line. But when the lines are drawn away from 90º or 0º, their edges are either horizontal or vertical. This means that when one of my lines is aligned horizontally, the 45º line is much thinner than the other.

image

I’m using the code below to create the lines. In the figure, the edges of the lines are both vertically oriented, and since the lineWidth argument sets the width by the edges, it makes the top line thinner than the horizontal line. Is there a way to fix this? (i.e., to get the edges displayed as if the lines are really thin rectangles as opposed to parallelograms.)

l1 = psychopy.visual.Line(
        win=win,
        lineWidth = 20,
        lineColor = [-1,1,1],
        units='height',
        interpolate=True
        )
l2 = psychopy.visual.Line(
        win=win,
        lineWidth = 20,
        lineColor = [-1,1,1],
        units='height',
        interpolate=True
        )


l1.setStart([0,0])
l1.setEnd([.1,0])

l2.setStart([0,0])
l2.setEnd([.1,.1])

l1.draw()
l2.draw()
win.flip()

Thanks!

Replying to my post since I found a solution. I don’t think there’s a good way to render lines with thicker edges such that the line width stays the same when the lines vary in orientation. This is because, if you’re using lineWidth to set the thickness of the lines, it’ll calculate the width based on the thickness of the edge. If your line is oriented at 45º, for example, as it was in the image on my original post, it’ll render a line such that the edge is rendered upright (and not perpendicular to the orientation of the line), and the height of the edge will be used to calculate the width.

The solution was to not use the Line stimuli. Instead, I used Rect to create a rectangle with the appropriate line width. I’ve included a function that takes in a line’s start and end points (l_start and l_end), its orientation in degrees (orientation), and line width (lw). It returns the vertices of a rectangle such that the original start and end points lie along the rectangle’s center.

def get_rect_vertices(l_start, l_end, orientation, lw):
    
    perp_or = np.radians(orientation + 90)
    start_v1 = l_start +(np.array([np.cos(perp_or), np.sin(perp_or)]) * lw) 
    start_v2 = l_start -(np.array([np.cos(perp_or), np.sin(perp_or)]) * lw) 

    end_v1 = l_end - (np.array([np.cos(perp_or), np.sin(perp_or)]) * lw) 
    end_v2 = l_end + (np.array([np.cos(perp_or), np.sin(perp_or)]) * lw)

    return np.array([start_v1, start_v2, end_v1, end_v2])

Hope this helps anyone who runs into the same issue!

1 Like