Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-12

Help with algorithm

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Leonardo M. Ramé

Hi, I'm trying to solve in a generic way this problem.

I have to paint a buffer into a Scanline, but taking into account the flipping and rotation of the resulting image, also part of the image can be displaced outside of the canvas only displaying the overlapping area of the buffer image.

Here's a diagram of what I need to draw (please use fixed fonts to read):

+----------- CANVAS ------------+
| |
| |
| +----- BUFFER IMAGE -----+
| |XXXXXXXXXXXXXXXXXX |
| |XXXXXXXXXXXXXXXXXX |
| |XXXXXXXXXXXXXXXXXX |
| |XXXXXXXXXXXXXXXXXX |
| |XXXXXXXXXXXXXXXXXX |
| |XXXXXXXXXXXXXXXXXX |
| |XXXXXXXXXXXXXXXXXX |
| +------------------------+
| |
| |
+-------------------------------+

Initially I calculated the overlapping rectangle (the part marked with X) then traversed from 0 to Y and 0 to X of that overlapped rectangle then painted each pixel into the scanline and incremented the buffer pointer. This worked really fast, but when taking into account Flipping I started adding specific code for each type of flip, I mean Vertical Flip, Horizontal Flip, Both, all by creating a function like PaintHFlip, PaintVFlip, etc. I really don't like this approach.

I'm thinking of copying the buffer into an two dimensional matrix, apply transformations, then extract the overlapping part and lastly paint. Before doing so, I'm asking here, because I'm afraid it could take too long to apply "n" transformations before displaying the final result.

Regards,

Reply by email

Mark Morgan Lloyd
to Leonardo M. Ramé
Leonardo M. Ram? wrote
I'm thinking of copying the buffer into an two dimensional matrix, apply transformations, then extract the overlapping part and lastly paint. Before doing so, I'm asking here, because I'm afraid it could take too long to apply "n" transformations before displaying the final result.

I'm not sure how far this helps, but my understanding is that if you implement each transformation as a matrix, you can multiply the transformations to get a final matrix which you only then apply to each point. That would reduce the problem to the (non-linear) operation of deciding whether each transformed pixel was in range of the canvas.

I did have a good reference for this sort of thing which I can't currently find, but
http://msdn.microsoft.com/en-us/library/windows/desktop/ff684171(v=vs.85).aspx looks like a reasonable starting point.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Hans-Peter Diettrich
to Leonardo M. Ramé: Hi, I'm trying to solve in a generic way this problem. I have to paint a buffer into a…
I'm thinking of copying the buffer into an two dimensional matrix, apply transformations, then extract the overlapping part and lastly paint.

Overlapping is typically handled in the graphics library (or card).

Before doing so, I'm asking here, because I'm afraid it could take too long to apply "n" transformations before displaying the final result.

That's my suspicion as well :-(

I'd suggest that you use some existing library for image processing, because these make use of hardware features built into graphics cards. That's how 3D animations work, which require more transformations than you intend to use. Details depend on your audience, i.e. a solution for your personal machine only, or for use on any machine.

Otherwise I'd implement specialized functions as you mentioned (VFlip, HFlip...), possibly with an wrapper that calls the appropriate functions. Then you also can exchange the implementation of the wrapper, with no impact on the rest of your program.

DoDi

Reply by email

Leonardo M. Ramé
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 24 lines
Leonardo M. Ram? schrieb: >I'm thinking of copying the buffer into an two dimensional matrix, apply >transformations, then extract the overlapping part and lastly paint. Overlapping is typically handled in the graphics library (or card). >Before doing so, I'm asking here, because I'm afraid it could take too >long to apply "n" transformations before displaying the final result. That's my suspicion as well :-( I'd suggest that you use some existing library for image processing, because these make use of hardware features built into graphics cards. That's how 3D animations work, which require more transformations than you intend to use. Details depend on your audience, i.e. a solution for your personal machine only, or for use on any machine. Otherwise I'd implement specialized functions as you mentioned (VFlip, HFlip...), possibly with an wrapper that calls the appropriate functions. Then you also can exchange the implementation of the wrapper, with no impact on the rest of your program.

Yes, but I'm trying to avoid if possible using 3rd party libraries, because I want to be able to easily port my program to HTML5 Canvas.

I'll try to create a transformation matrix, then fill it with the pointers from the buffer to see what I get, I'm pretty sure this is the way to go.

Regards,

Reply by email

Leonardo M. Ramé
to Mark Morgan Lloyd: I'm not sure how far this helps, but my understanding is that if you implement each…
Mark Morgan Lloyd wrote 18 lines
Leonardo M. Ram? wrote: >I'm thinking of copying the buffer into an two dimensional matrix, apply >transformations, then extract the overlapping part and lastly paint. >Before doing so, I'm asking here, because I'm afraid it could take too >long to apply "n" transformations before displaying the final result. I'm not sure how far this helps, but my understanding is that if you implement each transformation as a matrix, you can multiply the transformations to get a final matrix which you only then apply to each point. That would reduce the problem to the (non-linear) operation of deciding whether each transformed pixel was in range of the canvas. I did have a good reference for this sort of thing which I can't currently find, but http://msdn.microsoft.com/en-us/library/windows/desktop/ff684171(v=vs.85).aspx looks like a reasonable starting point.

Thanks, I'll try to implement it and apply to the buffer image.

Reply by email

Etienne Leblois

Greetings from Lyon, France,

In this kind of transformation, a *reverse* procedure to fill in the result from the source is typically needed with signature like

type TReverseProj = object
    // parameters to memorize
   procedure set( { some parameters} );
   procedure reverse(target_line, target_column :integer ; var
source_line, source_column :integer);
end;
procedure TReverseProj.set( { some parameters} );
begin
   // setting the parameters for the reverse transformation
end;
procedure TReverseProj.reverse(target_line, target_column :integer ; var
source_line, source_column :integer);
begin
   // applying the reverse transformation
end;

It is likely that the source position for "same_line_next column_in_target" can be written more simply that the full reverse (to be checked in equations, write on a paper reverse for (i,j) and (i,j+1) and see what is the difference).

To take benefit of this the last returned position must be memorized in the object and a routine added with signature like

procedure TReverseProj.shift_tarjet_cell(var
source_line_for_shifted_cell, source_column_for_shifted_cell :integer);
begin
   // shifting source according to the shift in cell
end;

So the full reverse will be called only at the begin of each line

For generality calculation and storage must be handled in floating point (single, double...) ; just the result is rounded.

Regards,

Etienne.

Reply by email