Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » Draw, Display, Images, Bitmaps, Icons » Painter and transformations
Painter and transformations [message #38837] Tue, 22 January 2013 18:29 Go to next message
mdelfede is currently offline  mdelfede
Messages: 1259
Registered: September 2007
Senior Contributor
Hi, usually (in many other geometric tools) this code

	painter.Translate(-jg.center);
	if(rot)
		painter.Rotate(-jg.angle);
	painter.Translate(dx, dy);

(do something with painter)

	painter.Translate(-dx, .dy);
	if(rot)
		painter.Rotate(jg.angle);
	painter.Translate(jg.center);



shiould behave exactly like this one :

	Xform2D trsf;
	trsf = Xform2D::Translation(-jg.center.x, -jg.center.y);
	if(rot)
		trsf = trsf * Xform2D::Rotation(-jg.angle);
	trsf = trsf * Xform2D::Translation(dx, dy);
	
	// translate painter to fit left joint center
	painter.Transform(trsf);

(do something with painter)

	trsf = Inverse(trsf);
	painter.Transform(trsf);


But it doesn't.... and I still don't understand how Upp does manage combined transformations.
By now I solved with second way, but I guess it would be by far more intuitive to fix the first one; each transformation should apply to "modified" reference done by former ones.

Anyways, it would be useful to add some member functions to Xform2d, to make possible to do something like this :

	Xform2d trsf = Xform2d().Translated(p).Rotated(a).Scaled(x);


Max

[Updated on: Tue, 22 January 2013 18:37]

Report message to a moderator

Re: Painter and transformations [message #38844 is a reply to message #38837] Wed, 23 January 2013 12:37 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12098
Registered: November 2005
Ultimate Member
Tried with this testcase:

#include <CtrlLib/CtrlLib.h>
#include <Painter/Painter.h>

using namespace Upp;

struct PainterTest : public TopWindow {
	virtual void Paint(Draw& w) {
		DrawPainter p(w, GetSize()/*, MODE_NOAA*/);

		p.Clear(White());
		p.Text(0, 0, "A", Roman(50));
		p.Fill(Black());
		
		p.Translate(100, 100);
		p.Rotate(1);
		p.Fill(Blue());

		p.Translate(200, -200);
		p.Scale(6);
		p.Fill(Magenta());
		
		p.Scale(1.0 / 6);
		p.Translate(-200, 200);
		
		p.Rotate(-1);
		p.Fill(Red());
		
		p.Translate(-100, -100);
		p.Fill(Green());
	}
};

GUI_APP_MAIN
{
	PainterTest().Run();
}



All seems ok...

[Updated on: Wed, 23 January 2013 12:38]

Report message to a moderator

Re: Painter and transformations [message #38850 is a reply to message #38844] Thu, 24 January 2013 00:23 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1259
Registered: September 2007
Senior Contributor
Hi Mirek, I'll append a sample test case which do the transformation in 2 ways, one with discrete commands (Translate, Rotate) and the other with a transformation matrix.
They shows the same drawing done in both ways in 2 controls aside; they should be identical (imho...) but on first one the image is not there because rotation shift out of control.

index.php?t=getfile&id=4024&private=0

The circle is just to show image center point; you can notice that the line is not on left picture, but it's displayed correctly on right one.

If I remove the rotation (in both paths), I get the correct image for boths, as following :

index.php?t=getfile&id=4026&private=0

It seems to me that rotation using discrete 'painter.Rotate()' command does the rotation around a wrong point... or am I missing something ?

Max
Re: Painter and transformations [message #38851 is a reply to message #38850] Thu, 24 January 2013 08:07 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12098
Registered: November 2005
Ultimate Member
You are not doing transformations right:

	Xform2D trsf;
	trsf = Xform2D::Translation(-center.x, -center.y);
	trsf = trsf * Xform2D::Rotation(angle);
	trsf = trsf * Xform2D::Translation(sz.cx / 2, sz.cy / 2);


You have reversed order of operands there, that is why you are getting different results.

Please refer to

http://en.wikipedia.org/wiki/Transformation_matrix#Composing _and_inverting_transformations

I have spend some time with your example to find out what is going on and it seems to me that everything behaves as expected (apart from the fact that the whole thing is perhaps not doing what you expect Wink

void Transformations::PaintImage(PaintingPainter &painter, Color color)
{
	Size sz = imageCtrl.GetSize();
	painter.Rectangle(0, 0, sz.cx, sz.cy);
	painter.Stroke(10, color);

	painter.Circle(0, 0, 50);
	painter.Fill(color);
	
	Pointf center(2000, 2000);
	painter.Text(2000, 2000, "A", Roman(400));
	painter.Fill(color);
}

void Transformations::Paint1()
{
	Size sz = imageCtrl.GetSize();
	PaintingPainter painter(sz);
	
	painter.Clear(White());

	painter.Scale(0.1, 0.1);
	painter.Translate(3000, 3000);
	
	
	painter.Scale(1, -1);
	painter.Translate(0, -sz.cy);
	
	PaintImage(painter, Black());

	Pointf center(2000, 2000);
	double angle = -45.0 * M_PI / 180;

	painter.Translate(-center);
	PaintImage(painter, Red());
	painter.Rotate(-angle);
	PaintImage(painter, Green());
	painter.Translate(sz.cx / 2, sz.cy / 2);
	PaintImage(painter, Blue());
	
	ImageDraw dw(sz);
	dw.DrawPainting(0, 0, sz.cx, sz.cy, painter);
	imageCtrl.SetImage(dw);
}

Re: Painter and transformations [message #38852 is a reply to message #38851] Thu, 24 January 2013 09:17 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1259
Registered: September 2007
Senior Contributor
Well, the purpose is :

1- Move te origin to 'center' point, aka have point (0,0) at 'center' point

2- Rotate the reference 45 AROUND CENTER

3- Move reference again to be on ImageCtrl center

4- Draw stuffs

5- Undo the transformation


That should (IMHO...) be done with

Translate(-center).Rotate(-angle).Translate(imagecenter)


So, maybe I understand Painter transformations wrong, but I still don't know how to have the thing to what I want Smile
Even more, if I remove the Rotate part it behaves as expected, so I guess that the problem (mine or Painter's one) it's the rotation center point.

BTW, you're right, I'm reversing the product's order in transformation matrices, but the weird is that if I do it right it doesn't work either....

Max
Re: Painter and transformations [message #38854 is a reply to message #38852] Thu, 24 January 2013 10:06 Go to previous message
mdelfede is currently offline  mdelfede
Messages: 1259
Registered: September 2007
Senior Contributor
Well, thanks to Mirek I got te point :

the last translation (used to center drawing on control) happens on a rotated reference, so it's wrong :

	painter.Translate(-center);
	painter.Rotate(angle);
	painter.Translate(sz.cx / 2, sz.cy / 2); <--WRONG


The weird part is that matrix way worked because it is reversed too, as Mirek explained correctly; so, to achieve the purpose it's enough to reverse transformation order (explanation is quite complex, but it works) :

	painter.Translate(sz.cx / 2, sz.cy / 2); <--WRONG
	painter.Rotate(angle);
	painter.Translate(-center);


This one does exactly what the matrix version do.

Max

Previous Topic: How must Alpha be managed ??
Next Topic: Crash in Painter
Goto Forum:
  


Current Time: Fri Nov 15 00:56:56 CET 2019

Total time taken to generate the page: 0.03687 seconds