From: Harm Subject: Re: 2d rotaion trouble! Date: 28 Mar 1999 00:00:00 GMT Message-ID: <36FE5D74.C74E566C@uswest.net> Content-Transfer-Encoding: 7bit References: Content-Type: text/plain; charset=us-ascii X-Complaints-To: abuse@uswest.net X-Trace: news.uswest.net 922639702 209.180.109.176 (Sun, 28 Mar 1999 10:48:22 CDT) Organization: Randomly Sorted MIME-Version: 1.0 Reply-To: harmans@uswest.net NNTP-Posting-Date: Sun, 28 Mar 1999 10:48:22 CDT Newsgroups: comp.graphics.algorithms Here's Delphi pascal code to rotate an image any angle, with edge wrapping, and anti-aliasing. Converted and added the edge wrapping, from original VB code by Rod Stephens. At least it wasn't (shudder) C++. :) procedure TForm1.RotateAngle(Angle: integer); var Theta, cosTheta, sinTheta: Single; cx, cy : Single; //Center X, Y sfrom_y, sfrom_x : Single; //Real number ifrom_y, ifrom_x : Integer; //Integer version to_y, to_x : Integer; weight_x, weight_y : array[0..1] of Single; weight : Single; new_red, new_green : Integer; new_blue : Integer; total_red, total_green : Single; total_blue : Single; ix, iy : Integer; pb, pc : pRGBArray; begin Screen.Cursor := crHourGlass; CopyMe(ud,b); //Copy to the undo bitmap CopyMe(tBufr,b); //Copy to the internal buffer bitmap // Calculate the sine and cosine of theta for later. Theta:=-(Angle)*Pi/180; sinTheta:=Sin(Theta); cosTheta:=Cos(Theta); cx := b.Width / 2; //Center of rotation for x cy := b.Height / 2; //Center of rotation for y // Perform the rotation. for to_y := 0 to b.Height-1 do begin for to_x := 0 to b.Width-1 do begin // Find the location (from_x, from_y) that // rotates to position (to_x, to_y). sfrom_x := cx + (to_x - cx) * cosTheta - (to_y - cy) * sinTheta; ifrom_x := Trunc(sfrom_x); sfrom_y := cy + (to_x - cx) * sinTheta + (to_y - cy) * cosTheta; ifrom_y := Trunc(sfrom_y); // Calculate the weights. if sfrom_y >= 0 then begin weight_y[1] := sfrom_y - ifrom_y; weight_y[0] := 1 - weight_y[1]; end else begin weight_y[0] := -(sfrom_y - ifrom_y); weight_y[1] := 1 - weight_y[0]; end; if sfrom_x >= 0 then begin weight_x[1] := sfrom_x - ifrom_x; weight_x[0] := 1 - weight_x[1]; end else begin weight_x[0] := -(sfrom_x - ifrom_x); Weight_x[1] := 1 - weight_x[0]; end; if ifrom_x < 0 then ifrom_x := b.Width -1-(-ifrom_x mod b.Width) else if ifrom_x > b.Width-1 then ifrom_x := ifrom_x mod b.Width; if ifrom_y < 0 then ifrom_y := b.Height -1-(-ifrom_y mod b.Height) else if ifrom_y > b.Height-1 then ifrom_y := ifrom_y mod b.Height; // Average the color components of the four // nearest pixels in from_canvas. total_red := 0.0; total_green := 0.0; total_blue := 0.0; for ix := 0 to 1 do begin for iy := 0 to 1 do begin if ifrom_y + iy < b.Height then pc := tBufr.ScanLine[ifrom_y + iy] else pc := tBufr.ScanLine[b.Height - ifrom_y - iy]; if ifrom_x + ix < b.Width then begin new_red := pc[ifrom_x + ix].rgbtRed; new_green := pc[ifrom_x + ix].rgbtGreen; new_blue := pc[ifrom_x + ix].rgbtBlue; weight := weight_x[ix] * weight_y[iy]; total_red := total_red + new_red * weight; total_green := total_green + new_green * weight; total_blue := total_blue + new_blue * weight; end else begin new_red := pc[b.Width - ifrom_x - ix].rgbtRed; new_green := pc[b.Width - ifrom_x - ix].rgbtGreen; new_blue := pc[b.Width - ifrom_x - ix].rgbtBlue; weight := weight_x[ix] * weight_y[iy]; total_red := total_red + new_red * weight; total_green := total_green + new_green * weight; total_blue := total_blue + new_blue * weight; end; end; end; pb := b.ScanLine[to_y]; pb[to_x].rgbtRed := Round(total_red); pb[to_x].rgbtGreen := Round(total_green); pb[to_x].rgbtBlue := Round(total_blue); end; end; imSine.Picture.Assign(b); //all done, assign the bmp to our image Screen.Cursor := crDefault; end; morphix wrote: > I have some problems figuring how to do a 2d rotation on an image. The > resulting image has blank pixels (holes that isn't filled with color) > could anybody please show me an algorithm that works, (pascal, c, c++ or > pseudo) > > Morphix -- Harmans Omaha NE