Copying an inclined area to a horizontal one?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
agesome
Prole
Posts: 3
Joined: Sat Apr 06, 2013 12:26 am

Copying an inclined area to a horizontal one?

Post by agesome »

Hi.

For my little project, I need to take a line (say, all pixels along a diagonal line) from an image and copy it to another image, one pixel high. As if taken with a line scan camera.
The most obvious way would seem to use a quad and render it to that one-pixel-high image, but apparently that's not possible (or so I've been told on IRC).
Then, I tried using ImageData and copying the pixels by hand. That seemed to work, but looks dirty and slow.

So, is there a way to take a non-horizontal area of an image, rotate it horizontally and store it in another image?
If there's no way to do that, would it work if I patched Love's OpenGL code to rotate quads?
agesome
Prole
Posts: 3
Joined: Sat Apr 06, 2013 12:26 am

Re: Copying an inclined area to a horizontal one?

Post by agesome »

Love is indeed all-powerful. I have achieved desired function by rotating a Canvas' coordinate system around my line's origin point and drawing on it the image with the needed linear area now horizontal.

I actually needed this to take a sample of a racetrack image, simulating a line scan camera. Screenshot:
Image
(The green line is the sampling line, you can see results in upper left corner)

Relevant source code:

Code: Select all

local M = {}

local FRAME_LEN = 128
local sampling_angle = math.rad (90)
local x_shift = math.sin (sampling_angle + math.rad(90)) * FRAME_LEN
local y_shift = math.cos (sampling_angle + math.rad(90)) * FRAME_LEN

function M.sample(image, x, y)
	local w, h = image:getWidth(), image:getHeight()
	local canvas = love.graphics.newCanvas (w, h)
	local line = love.image.newImageData (FRAME_LEN, 1)

	love.graphics.push ()
	love.graphics.translate (x, y)
	love.graphics.rotate (sampling_angle)
	love.graphics.translate (-x, -y)
	canvas:renderTo (
		function ()
			love.graphics.draw (image, 0, 0)		
		end
	)
	love.graphics.pop ()
	local image_data = canvas:getImageData ()

	for i = 0, (FRAME_LEN - 1) do
		line:setPixel (i, 0, image_data:getPixel (x + i, y))
	end

	love.graphics.line (x, y, x + x_shift, y + y_shift)
	return love.graphics.newImage (line)
end

function M.set_sampling_angle(deg)
	sampling_angle = math.rad (deg)
	x_shift = math.sin (sampling_angle + math.rad(90)) * FRAME_LEN
	y_shift = math.cos (sampling_angle + math.rad(90)) * FRAME_LEN
end

return M
User avatar
Ragzouken
Citizen
Posts: 84
Joined: Fri Aug 10, 2012 7:59 am
Contact:

Re: Copying an inclined area to a horizontal one?

Post by Ragzouken »

You found a solution whilst I was writing this, but I'll post it anyway for anyone who might be interested:

It will be possible will Geometry, which I understand will be in 0.9.0, so if it's not urgent then I'd hold your horses on patching love yourself.

You could hack it will a pixel effect, but that's probably a bad idea for compatibility reasons. If you did want to do that for now though, the effect would be something like:

Code: Select all

extern number w, h; // width/height of source image
extern number ox, oy, a; // line start and angle

vec4 effect(vec4 colour, Image image, vec2 local, vec2 pixel)
{
    vec2 source = vec2(ox + cos(a) * pixel.x, oy + sin(a) * pixel.x);

    source.x /= w;
    source.y /= h;

    return Texel(image, source);
}
agesome
Prole
Posts: 3
Joined: Sat Apr 06, 2013 12:26 am

Re: Copying an inclined area to a horizontal one?

Post by agesome »

Ragzouken, I have opted for your solution for now. Thank you. My approach turned out to be more difficult to use, especially because line angle is constantly changing.
Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests