worldToScreen(1.0) * g_approxScale

View: New views
8 Messages — Rating Filter:   Alert me  

worldToScreen(1.0) * g_approxScale

by Petr Kobalíček :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi devs,

I have question about 'worldToScreen(1.0) * g_approxScale' code in Agg2d.

g_approxScale is 2 and worldToScreen() does scalar transform (I
think), but how this code is related to output quality of image?

Another question is that if there is no transform (identity matrix) is
this code needed?

I'm not using Agg2d, I'm now working to integrate BlitJit and
Antigrain in my library and I don't perfectly understand steps that
are related to drawing transformed paths / images. I wan't also to
contribute agg with BlitJit support, but it's too much work to get
blitjit to work.

Thank you
- Petr

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: worldToScreen(1.0) * g_approxScale

by Lorne Laliberte :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Apr 23, 2009 at 6:16 PM, Petr Kobalíček
<kobalicek.petr@...> wrote:
> Hi devs,
>
> I have question about 'worldToScreen(1.0) * g_approxScale' code in Agg2d.
>
> g_approxScale is 2 and worldToScreen() does scalar transform (I
> think), but how this code is related to output quality of image?

AGG breaks curves into a series of very short straight segments. The
length of those segments needs to change at different scaling levels
in order to continue looking like curves instead of a series of
straight lines.

The approximation scale tells AGG what scaling factor to use when
sizing those "curve-approximating segments."

The goal is to use enough straight line segments to keep the curve
looking like a curve, while using as few segments as possible to
maximize performance.

> Another question is that if there is no transform (identity matrix) is
> this code needed?

Not generally, no. :) But it can be useful if you *want* to make a
curve look like a series of straight line segments. For example, it
can be useful when generating point samples from a curve for various
uses.

Lorne Laliberte
Senior Software Developer, Indigo Rose Software

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: worldToScreen(1.0) * g_approxScale

by Stephan Assmus :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 2009-04-24 at 09:03:11 [+0200], Lorne Laliberte <lorne@...>
wrote:

> On Thu, Apr 23, 2009 at 6:16 PM, Petr Kobalíček
> <kobalicek.petr@...> wrote:
> > Hi devs,
> >
> > I have question about 'worldToScreen(1.0) * g_approxScale' code in
> > Agg2d.
> >
> > g_approxScale is 2 and worldToScreen() does scalar transform (I think),
> > but how this code is related to output quality of image?
>
> AGG breaks curves into a series of very short straight segments. The
> length of those segments needs to change at different scaling levels in
> order to continue looking like curves instead of a series of straight
> lines.
>
> The approximation scale tells AGG what scaling factor to use when sizing
> those "curve-approximating segments."
>
> The goal is to use enough straight line segments to keep the curve
> looking like a curve, while using as few segments as possible to maximize
> performance.

Maybe I can add something to what Lorne said... you need to consider the
situation where the code that breaks a curve into segments doesn't know
about any transformations that are still performed on the output of it's
operation. The segment generation assumes that the curve is already in
screen (world) coordinates and generates curves that would look good if
this assumption were true. If you then transform the output from the
segmentation and scale it up two times, then too few segments have been
generated for this transformation. This is where approximation scale comes
into play. The best situation is when you have exactly one transformation
from local to world coordinates, like when you combine multiple
transformations within an object hierarchy into one "to world"
transformation per object. Then you can just use the scale() value from
that transformation as the approximation scale for that object. All that
being said, I have no clue about where "worldToScreen(1.0) * g_approxScale"
is used in Agg2d. It looks a bit weird, since the approximation scale
should not be something global, but something that applies to the
individual world transformation of each object. But maybe the value is
adjusted according to the current world transformation. In any case, it
should be a dynamic value that depends on the current world transformation,
not a constant.

Best regards,
-Stephan

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: worldToScreen(1.0) * g_approxScale

by Lorne Laliberte :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/4/24 Stephan Assmus <superstippi@...>:

> Maybe I can add something to what Lorne said...

Another very useful elaboration Stephen, thanks. :)

> All that
> being said, I have no clue about where "worldToScreen(1.0) * g_approxScale"
> is used in Agg2d. It looks a bit weird, since the approximation scale
> should not be something global, but something that applies to the
> individual world transformation of each object.

That worldToScreen(1.0) call is using the current transformation
associated with Agg2d's coordinate conversion pipeline. The
g_approxScale is just an additional global modifier that Agg2d
provides for whatever reason. (Kind of like how you can set alpha for
some things individually but also set a global gamma adjustment...).

> But maybe the value is
> adjusted according to the current world transformation.

Yep, that's what the worldToScreen() call is doing.

I don't use Agg2d either (it really just scratches the surface of
what's possible in agg), but I studied it back when I was first coming
to grips with AGG.

Lorne Laliberte
Senior Software Developer, Indigo Rose Software

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: worldToScreen(1.0) * g_approxScale

by Stephan Assmus :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 2009-04-24 at 10:49:18 [+0200], Lorne Laliberte <lorne@...>
wrote:
> 2009/4/24 Stephan Assmus <superstippi@...>:
>
> > Maybe I can add something to what Lorne said...
>
> Another very useful elaboration Stephen, thanks. :)

Ups... sorry! I just wasn't sure if it became clear yet... I am not even
sure if it becomes clear from what I said at all, since I fail to mention
what objects even have the set_approximation_scale() methods, if he is
using Agg2D and not AGG directly, it may be a mystery still... :-)

> > All that
> > being said, I have no clue about where "worldToScreen(1.0) *
> > g_approxScale" is used in Agg2d. It looks a bit weird, since the
> > approximation scale should not be something global, but something that
> > applies to the individual world transformation of each object.
>
> That worldToScreen(1.0) call is using the current transformation
> associated with Agg2d's coordinate conversion pipeline. The g_approxScale
> is just an additional global modifier that Agg2d provides for whatever
> reason. (Kind of like how you can set alpha for some things individually
> but also set a global gamma adjustment...).

Ah! That makes sense.

> > But maybe the value is
> > adjusted according to the current world transformation.
>
> Yep, that's what the worldToScreen() call is doing.

Thanks for clearing that up. I was beginning to guess it when I typed up my
previous mail, Agg2D works like a graphics state stack, correct?

Best regards,
-Stephan

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: worldToScreen(1.0) * g_approxScale

by Petr Kobalíček :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

many thanks for comments, I need time to get it working and I there
will be problems I will ask again.

Only small notes about what I asked and how I now understand it. I
asked because I used these lines of code:

void Agg2D::roundedRect(double x1, double y1, double x2, double y2, double r)
{
    m_path.remove_all();
    agg::rounded_rect rc(x1, y1, x2, y2, r);
    rc.normalize_radius();
    rc.approximation_scale(worldToScreen(1.0) * g_approxScale); // <---- Here
    // JME audit
    //m_path.add_path(rc, 0, false);
    m_path.concat_path(rc,0);
    drawPath(FillAndStroke);
}

but in another function it itsn't :

void Agg2D::roundedRect(double x1, double y1, double x2, double y2,
double rx, double ry)
{
    m_path.remove_all();
    agg::rounded_rect rc;
    rc.rect(x1, y1, x2, y2);
    rc.radius(rx, ry);
    rc.normalize_radius();
    //m_path.add_path(rc, 0, false);
    m_path.concat_path(rc,0); // JME
    drawPath(FillAndStroke);
}

So this is bug or I not perfectly understand problem:)

And my understanding is here: drawing path needs lines and curves
vertexes and agg::rounded_rect output are lines instead of curves so
the routine must be sure that these lines will look like curves if
different scaling than 1.0 is set. Solution can be to create rounded
rect through moveTo, lineTo and curveTo steps.

Cheers
- Petr

2009/4/24 Stephan Assmus <superstippi@...>:

>
> On 2009-04-24 at 10:49:18 [+0200], Lorne Laliberte <lorne@...>
> wrote:
>> 2009/4/24 Stephan Assmus <superstippi@...>:
>>
>> > Maybe I can add something to what Lorne said...
>>
>> Another very useful elaboration Stephen, thanks. :)
>
> Ups... sorry! I just wasn't sure if it became clear yet... I am not even
> sure if it becomes clear from what I said at all, since I fail to mention
> what objects even have the set_approximation_scale() methods, if he is
> using Agg2D and not AGG directly, it may be a mystery still... :-)
>
>> > All that
>> > being said, I have no clue about where "worldToScreen(1.0) *
>> > g_approxScale" is used in Agg2d. It looks a bit weird, since the
>> > approximation scale should not be something global, but something that
>> > applies to the individual world transformation of each object.
>>
>> That worldToScreen(1.0) call is using the current transformation
>> associated with Agg2d's coordinate conversion pipeline. The g_approxScale
>> is just an additional global modifier that Agg2d provides for whatever
>> reason. (Kind of like how you can set alpha for some things individually
>> but also set a global gamma adjustment...).
>
> Ah! That makes sense.
>
>> > But maybe the value is
>> > adjusted according to the current world transformation.
>>
>> Yep, that's what the worldToScreen() call is doing.
>
> Thanks for clearing that up. I was beginning to guess it when I typed up my
> previous mail, Agg2D works like a graphics state stack, correct?
>
> Best regards,
> -Stephan
>
> ------------------------------------------------------------------------------
> Crystal Reports - New Free Runtime and 30 Day Trial
> Check out the new simplified licensign option that enables unlimited
> royalty-free distribution of the report engine for externally facing
> server and web deployment.
> http://p.sf.net/sfu/businessobjects
> _______________________________________________
> Vector-agg-general mailing list
> Vector-agg-general@...
> https://lists.sourceforge.net/lists/listinfo/vector-agg-general
>

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: worldToScreen(1.0) * g_approxScale

by Milan Marusinec :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Petr Kobalíček wrote:
> void Agg2D::roundedRect(double x1, double y1, double x2, double y2, double r)
> {
>     m_path.remove_all();
>     agg::rounded_rect rc(x1, y1, x2, y2, r);
>     rc.normalize_radius();
>     rc.approximation_scale(worldToScreen(1.0) * g_approxScale); // <---- Here

Peter,

This ensures that rounded corners gets properly segmentated
at any transformations (eg. zoom/scale), because
the "worldToScreen" function takes the current matrix
in account while "g_approxScale" is constant.

>     // JME audit
>     //m_path.add_path(rc, 0, false);
>     m_path.concat_path(rc,0);
>     drawPath(FillAndStroke);
> }

--
Milan Marusinec
http://www.CrossGL.com


------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: worldToScreen(1.0) * g_approxScale

by Stephan Assmus :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 2009-04-24 at 13:23:07 [+0200], Petr Kobalíček
<kobalicek.petr@...> wrote:

> Hi,
>
> many thanks for comments, I need time to get it working and I there will
> be problems I will ask again.
>
> Only small notes about what I asked and how I now understand it. I asked
> because I used these lines of code:
>
> void Agg2D::roundedRect(double x1, double y1, double x2, double y2,
> double r) {
>     m_path.remove_all();
>     agg::rounded_rect rc(x1, y1, x2, y2, r);
>     rc.normalize_radius();
>     rc.approximation_scale(worldToScreen(1.0) * g_approxScale); // <----
>     Here // JME audit
>     //m_path.add_path(rc, 0, false);
>     m_path.concat_path(rc,0);
>     drawPath(FillAndStroke);
> }
>
> but in another function it itsn't :
>
> void Agg2D::roundedRect(double x1, double y1, double x2, double y2,
> double rx, double ry)
> {
>     m_path.remove_all();
>     agg::rounded_rect rc;
>     rc.rect(x1, y1, x2, y2);
>     rc.radius(rx, ry);
>     rc.normalize_radius();
>     //m_path.add_path(rc, 0, false);
>     m_path.concat_path(rc,0); // JME
>     drawPath(FillAndStroke);
> }
>
> So this is bug or I not perfectly understand problem:)

I assume it's a bug and it also serves as an excellent example of why code
duplication is bad! The second version which takes separate x and y radius
should set the approximation scale (like the first version does) and the
first version should simply call the second version with y radius == x
radius.

> And my understanding is here: drawing path needs lines and curves
> vertexes and agg::rounded_rect output are lines instead of curves so the
> routine must be sure that these lines will look like curves if different
> scaling than 1.0 is set. Solution can be to create rounded rect through
> moveTo, lineTo and curveTo steps.

Yes, that's why the approximation scale needs to be set on the round rect
object. Otherwise the straight line segments may be wrong for the current
global scale. It should not be necessary to generate the round rect
yourself.

Best regards,
-Stephan

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general