Hi,
I have an image which I want to rotate, how can I do that?
CBitmapRotator rotates the image but is rotates only increments of 90 degrees. I want more gradual rotations some thing like a clock' hand.
Let me know if it is possible or not?
Hi,
I have an image which I want to rotate, how can I do that?
CBitmapRotator rotates the image but is rotates only increments of 90 degrees. I want more gradual rotations some thing like a clock' hand.
Let me know if it is possible or not?
Regards,
Ashish
OpenGL (where available) can rotate images for you by arbitrary angles.
However if you are familiar with computer graphics, implementing a DDA rotator is a more viable approach.
Hi wizard_hu_,
Can you give me a piece of code, to see how to use DDA Rotator. Because, I tried to use CBitmapRotator :
http://discussion.forum.nokia.com/fo...ad.php?t=78470
But it doesn't work.
Thank you very much.
Bernie
For example, you can implement a DDA class:
Code:class TBasicDda { public: TBasicDda(TInt aFrom,TInt aTo,TInt aSteps); void Step(); TInt iCurrent; private: TInt iDir; TInt iDelta; TInt iCounter; TInt iDivident; }; TBasicDda::TBasicDda(TInt aFrom,TInt aTo,TInt aSteps) { iCurrent=aFrom; iDir=aFrom<aTo?1:-1; iDelta=iDir*(aTo-aFrom); iCounter=-iDelta; iDivident=aSteps; } void TBasicDda::Step() { if(iDivident==0) return; iCounter+=iDelta; while(iCounter>=iDivident) { iCurrent+=iDir; iCounter-=iDivident; } }
And wrap around a 2D texture mapper:
Code:class CRender:public CBase { public: static CRender *NewL(TRect aRect); ~CRender(); void Line(TPoint aP1,TPoint aT1,TPoint aP2,TPoint aT2); void Flush(CFbsBitmap &aTexture,CGraphicsContext &aTarget); private: void ConstructL(); TRect iRect; TInt *iLeft; TInt *iLeftU; TInt *iLeftV; TInt *iRight; TInt *iRightU; TInt *iRightV; }; CRender* CRender::NewL(TRect aRect) { CRender *self=new(ELeave)CRender; CleanupStack::PushL(self); self->iRect=aRect; self->ConstructL(); CleanupStack::Pop(); return self; } CRender* CRender::NewL(TRect aRect) { CRender *self=new(ELeave)CRender; CleanupStack::PushL(self); self->iRect=aRect; self->ConstructL(); CleanupStack::Pop(); return self; } void CRender::ConstructL() { TInt h=iRect.Height(); iLeft=new(ELeave)TInt[h]; iLeftU=new(ELeave)TInt[h]; iLeftV=new(ELeave)TInt[h]; iRight=new(ELeave)TInt[h]; iRightU=new(ELeave)TInt[h]; iRightV=new(ELeave)TInt[h]; for(TInt i=0;i<h;i++) { iLeft[i]=iRect.iBr.iX+1; iRight[i]=iRect.iTl.iX-1; } } CRender::~CRender() { delete[] iLeft; delete[] iLeftU; delete[] iLeftV; delete[] iRight; delete[] iRightU; delete[] iRightV; } void CRender::Line(TPoint aP1,TPoint aT1,TPoint aP2,TPoint aT2) { if(aP1.iY==aP2.iY) return; if(aP1.iY>aP2.iY) { TPoint temp=aP1; aP1=aP2; aP2=temp; temp=aT1; aT1=aT2; aT2=temp; } aP1.iY-=iRect.iTl.iY; aP2.iY-=iRect.iTl.iY; TInt h=iRect.Height(); TBasicDda x(aP1.iX,aP2.iX,aP2.iY-aP1.iY); TBasicDda u(aT1.iX,aT2.iX,aP2.iY-aP1.iY); TBasicDda v(aT1.iY,aT2.iY,aP2.iY-aP1.iY); for(TInt y=aP1.iY;y<=aP2.iY;y++) { if(y>=0 && y<h) { if(x.iCurrent<iLeft[y]) { iLeft[y]=x.iCurrent; iLeftU[y]=u.iCurrent; iLeftV[y]=v.iCurrent; } if(x.iCurrent>iRight[y]) { iRight[y]=x.iCurrent; iRightU[y]=u.iCurrent; iRightV[y]=v.iCurrent; } } x.Step(); u.Step(); v.Step(); } } void CRender::Flush(CFbsBitmap &aTexture,CGraphicsContext &aTarget) { aTarget.SetPenStyle(CGraphicsContext::ESolidPen); aTarget.SetPenSize(TSize(1,1)); aTarget.SetDrawMode(CGraphicsContext::EDrawModePEN); TInt h=iRect.Height(); for(TInt y=0;y<h;y++) { if(iLeft[y]<=iRect.iBr.iX && iRight[y]>=iRect.iTl.iX) { TBasicDda u(iLeftU[y],iRightU[y],iRight[y]-iLeft[y]); TBasicDda v(iLeftV[y],iRightV[y],iRight[y]-iLeft[y]); for(TInt x=iLeft[y];x<=iRight[y];x++) { if(x>=iRect.iTl.iX && x<=iRect.iBr.iX) { TRgb rgb; aTexture.GetPixel(rgb,TPoint(u.iCurrent,v.iCurrent)); aTarget.SetPenColor(rgb); aTarget.Plot(TPoint(x,y+iRect.iTl.iY)); } u.Step(); v.Step(); } } } }
Example usage:
Code:void CTestAppView::Draw(const TRect& /*aRect*/) const { CWindowGc& gc = SystemGc(); TRect drawRect = Rect(); gc.Clear(); drawRect.Shrink(70,10); CRender *r=CRender::NewL(drawRect); CleanupStack::PushL(r); TSize s=iBitmap->SizeInPixels(); r->Line(TPoint(50,20),TPoint(0,0),TPoint(120,40),TPoint(s.iWidth,0)); r->Line(TPoint(120,40),TPoint(s.iWidth,0),TPoint(100,110),TPoint(s.iWidth,s.iHeight)); r->Line(TPoint(100,110),TPoint(s.iWidth,s.iHeight),TPoint(30,90),TPoint(0,s.iHeight)); r->Line(TPoint(30,90),TPoint(0,s.iHeight),TPoint(50,20),TPoint(0,0)); r->Flush(*iBitmap,gc); CleanupStack::PopAndDestroy(); //some outlining gc.SetPenColor(TRgb(0,0,0)); gc.DrawRect(drawRect); gc.DrawLine(TPoint(50,20),TPoint(120,40)); gc.DrawLine(TPoint(120,40),TPoint(100,110)); gc.DrawLine(TPoint(100,110),TPoint(30,90)); gc.DrawLine(TPoint(30,90),TPoint(50,20)); }
Sorry ppl...
I am digging an old old file...
Wizard_hu...
I am following this code for rotation..
I am getting the rotated image ...(Its around 35-50 degree,i think)
But the image is too small in dimension...
But where to set the dimensions and angles???
Pls if u tell me i will continue with my work on rotation....
You need some trigonometry for that.
If you have an origo-centered rectangle with coordinates
-a, b (top-left corner)
a, b (top-right corner)
a,-b (bottom-right corner)
-a,-b (bottom-left corner)
The new coordinates after rotating with 35 degrees will become
-a * cos 35 - b * sin 35 , -a * sin 35 + b * cos 35
a * cos 35 - b * sin 35 , a * sin 35 + b * cos 35
a * cos 35 + b * sin 35 , a * sin 35 -b * cos 35
-a * cos 35 + b * sin 35 , -a * sin 35 -b * cos 35
Remember that Math::Sin/Cos expects argument in radians, so you will actually need 35*KPi/180 as argument.
Thanx wizard_hu_
I will finish off this thing...
Very much thanx..I hope that the rotation doesn't decrease the quality of the image..
Hi wizard_hu
can you give me a hint for your sample code in order to be understood ??
Thanks in advance
Which part?
DDA is about walking the points of an angular line.
If start point is (x1,y1), end point is (x2,y2), you could express y as function of x like
The twist with DDA (according to Wikipedia: Direct Differential Analyzer - though until now I was thinking Direct Digital Analyzer) is twofold:Code:(y2-y1) y(x) = y1 + ------- * (x-x1) (x2-x1)
- in computer graphics, you are interested in integer coordinates only, since on the monitor you never deal with coordinates like (5.5,6.789)
- in computers you do not necessarily like calculating with fractions/floating point numbers ("(y2-y1)/(x2-x1)" is not an integer number in most cases)
So DDA (or Bresenham's line, whichever you prefer) is tracking the changes of the integral part of the coordinates while you are walking that line. And for the fractional part, it tracks the nominator and the denominator separately, keeping in mind that the integer part changes when the nominator part crosses an integer multiple of the denominator - and since you already track the integer part separately, you can keep the reduced nominator between 0 and the denominator itself (or between -denominator and 0), so crossing a new boundary can be noticed via a simple comparison.
Let us assume that we want to draw a line between (0,0) and (3,2)
We initialize
x=0
y=0
nominator=0
denominator=x2-x1=3-0=3
increment=y2-y1=2-0=2
We draw the pixel on 0,0:ThenCode:. . .*
- increment x (x=1)
- increment nominator by "increment" (nominator=0+2=2)
- check if nominator if it is greater or equal to the denominator (2>=3? no)
Draw the next dot on (1,0)- increment x (x=2)Code:. . .**
- increment nominator by "increment" (nominator=2+2=4)
- check if nominator is greater or equal to the denominator (4>=3? yes)
-- increment y (y=1)
-- substract nominator from denominator (nominator=4-3=1)
-- if the line is steep, this may need to be repeated (starting with the check)
Draw the next dot on (2,1)- increment x (x=3)Code:. . * .**
- increment nominator by "increment" (nominator=1+2=3)
- check if nominator is greater or equal to the denominator (3>=3? yes)
-- increment y (y=2)
-- substract nominator from denominator (nominator=3-3=0)
Draw the final dot on (3,2)In fact it can be seen that I was cheating: the line is distorted because the depicted algorithm does not calculate "rounded" y coordinate, but it calculates a "truncated" one (always rounds "downwards").Code:. * . * .**
A nicer implementation would calculate with doubled denominator and increment, and initialize nominator with x2-x1, which would actually mean that the points are sampled at the middle of each pixel (starting from (0.5,0.5)) and result in a smoother lineAnyway, in fact Symbian comes with a DDA implementation (TLinearDDA in gdi.h), but I was not aware of that by the time of writing.Code:. * . ** .*
The other code is about drawing "lines" using the DDA: 2D texturing is about sampling the texture using straight lines.
Last edited by wizard_hu_; 2009-02-05 at 14:21. Reason: "."-s are included for maintaining vertical position of "scanlines"
I've used CBitmapRotatorto rotate the image , I followed that link
http://wiki.forum.nokia.com/index.ph...CBitmapRotator
and in container class InitializeControlsL() function I used CBitmapRotatorHandler class
as
but the image not rotatedCode:iBitmapRotator = CBitmapRotatorHandler::NewL(*this); iBitmapRotator->Rotate(*bitmap, CBitmapRotator::ERotation90DegreesClockwise); iImage1->SetPicture( bitmap, mask ); } iImage1->SetAlignment( EHCenterVTop );
what is the problem ?? sorry for repeat my question but i need help
contact http://www.origoide.com/contact.html for help.
note: dipika, your post is no way related to original post. also does not look like a development problem any way.