Drawing Oval with Gdk Cairo Context - graphics

I want to draw only the circumference of an oval. I use this:
gc->save();
gc->translate( xc, yc );
gc->arc( 0.0, 0.0, 1.0, 0.0, 2.0*M_PI );
gc->scale( width*0.5, height*0.5 );
gc->stroke();
gc->restore();
but I constantly get a filled oval. What am I doing wrong?

Well, your call to scale() is probably not doing what you intended. I'm not sure if you accidentally put the calls in the wrong order, or if you don't quite understand how cairo's transformations work. In case it's the latter:
Transformations only affect the following operations. And they only affect operations involving coordinates or sizes somehow. In this case, you likely wanted to apply it to the arc. However, it's actually only getting applied to the stroke, and likely in a way you did not intend.
Know how I mentioned transforms affect operations involving coordinates or sizes? Well, it might not be obvious, but stroke does implicitly involve sizes: namely, the stroke size. So your arc's stroke size gets scaled by width * 0.5 on the x axes and height * 0.5 on the y axes. In other words, the stroke is so friggin' huge it looks like a fill.
Interestingly, even though your arc was actually unaffected by scale(), which means you would have been left with a circle instead of an oval, you still wound up with an oval because of the way the stroke was scaled.
So, to fix your issue:
call scale() before arc()
reset the scaling factor after you call arc() but before you call stroke(), so that you don't wind up with the monstrous stroke again

Related

SVG arc slips away as it completes it's arc

http://codepen.io/andrewplummer/pen/pyjjbJ
I'm trying to make a simple arc for a graph. I've read up on "A a" arc in SVG and I believe I understand the specifics, but when the arc approaches its origin point it starts slipping to the right and I can't figure out why.
The main problems seems to be here: <path d="M75 5 A70 70 0 1 1 71 6" stroke="#3f51b5"></path>. As the closing point (71 76) approaches the origin (75 5) the arc starts to shift to the right. The pen shows more details... All browsers show this behavior so it doesn't seem to be a bug.
If you need accuracy, then don't try to draw a complete 360deg arc with one path arc command. Because you don't specify the centre point when describing arcs, tiny mathematical inaccuracies between the combination of start point, end point and radiuses can cause the arc to shift around by quite a surprising amount.
I would suggest keeping your arcs to a maximum of 180 degrees. For large radiuses you may want to go even lower, and limit it to 90 degrees.
As it turns out, it's the call to Math.ceil that was causing this issue. It appears that even small changes in the final x/y position (the last 2 arguments to the svg A command) can have big effects on the resulting arc. When drawing larger arcs these smaller differences can have more exaggerated effects, so #Paul LeBeau's answer is somewhat correct. However, simply not rounding fixed the issue and renders perfectly so it seems that one arc will in fact do the trick, just don't round (rounding pixel values is kind of a force of habit for older devs used to crappy browsers).
The arc command has two flags, the attached image should explain it.
Are you trying to draw a complete circle ?

Making far objects look fading or transparent

I have a 3D rectangle, rotated 45 degrees as in the attached screenshot. I would like the lines and the far edge (A) to look fading. Moreover, when i rotate the camera, i want the 'new' far lines and edges to look fading. So if B will be in the place if A, B and the lines to B will look fading. How can i do that?
If it makes any difference, i use OpenGL ES 2.0 on iOS.
I'd suggest enabling alpha blending and in your pixel shader you set the resulting color's alpha value based on the depth.
Something like result.a = clamp(1.0/(-gl_FragCoord.z + 1.0), 0.0, 1.0) might work.

Smoothing overlapping stroke edges

I'm using Raphael to draw the arcs as shown in the image below:
Z-index order is from lowest to highest: gray, blue, green.
Both the gray and the blue arcs start from the top, where the green one starts.
Is there any way to improve the edges? Especially the green over blue one.
Thank you.
I'm afraid there's not much you can do. How the shape is rendered depends on the viewer (browser, image viewer or importing application). You could play with the rendering properties and see if this gives you an improvement, but I believe hardly any SVG implementation supports them.
I am not sure exactly what you mean, and it is hard to know how you made the image without the raphael code. Are you talking about the way the outer edge of the green arc extends slightly beyond the outer edge of the blue arc? I would check that the corner points of the two paths are the same, and include the stroke-width in your calculations of the paths.
Perhaps you could try reducing the stroke-width to 0 to make things easier.
The problem is that you are overlapping the shapes. This causes some colors to spill out from underneath. To solve this you need to start each arc where the previous one ends.
You might get very faint gaps, this can easily solved by applying a 1px stroke to each arc.

Frustum position, origin and culling

I am writing a simple program that uses perspective projection and I have a bunch of objects drawn in my scene. For perspective projection I am using the following code:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluLookAt(eyePosX, eyePosY, eyePosZ, centerPosX, centerPosY, centerPosZ, 0.0, 1.0, 0.0);
glFrustum(frustumLeft,frustumRight,frustumBottom,frustumTop,frustumNear,frustumFar);
When I have an object drawn with a certain offset on the X axis that does not inside into the frustum, the object is stil drawn, but is elongated and not culled by the frustum.
What are the coordinates of the 8 points in the XYZ space with respect to eyePosX/Y/Z and frustumLeft/Right/Bottom/Top/Near/Far?
How can I tell OpenGL to perform the culling of the objects that are not inside the frustum?
For perspective projection I am using the following code:
There are two possibilities. The first is that you really didn't mean to do what this code does. The second is that you did mean it, but don't fully understand what you've done.
Let's cover the first one now. The look-at matrix should never go inside the GL_PROJECTION matrix. Also, the look-at matrix always comes after the projection matrix. These should always be true unless you're doing something special.
Which leads to the second. If you really intend to rotate and offset the post-projective space, then you cannot expect geometry to be culled against the frustum. Why?
Because OpenGL doesn't do frustum culling. It culls against whatever post-T&L vertex positions you provide. If you rotate the view outside of the frustum, then that's what gets drawn. OpenGL doesn't draw what isn't visible; if you change the view post-projection so that things that wouldn't have been visible are visible now, then you've changed what is and is not visible.

WebGL / Box2D drawing issue: gap between bodies

I'm still a graphics programming novice and bet the following problem is just a matter of wrong configuration.
i am creating a game using webgl for graphics and box2dweb for physics. unfortunately the drawing shows gaps between the physical bodies (left is my actual rendering, right is a rendering using box2dweb's debug-drawing in another canvas):
both box2d and webgl use the same coordinate-system and sizes for the boxes. there is no conversion. the red boxes are actually textures, though this doesn't make a difference. the red boxes are dynamic bodies, the green boxes are static bodies.
obviously i can't just resize graphics or physics. if i made the graphics bigger, the green boxes would overlap, if made physics smaller there will be physics-gaps.
here is another example:
also, sometimes, there there is no gap just like in the following (just moved the physic-bodies a little on the right)
the black boxes are just color-drawn (no textures). looking at the previous image, i guess it has to do with converting the floating-world-coordinates to screen-pixel-coordinates, but i have no idea what the option for fixing this would be.
Thanks a lot for the help
[Update]
It is an ortographic projection matrix, that I am initializing in the following way:
mat4.ortho(-this.vpWidth * this.zoom, this.vpWidth * this.zoom, -this.vpHeight * this.zoom, this.vpHeight * this.zoom, 0.1, 100.0, this.pMatrix);
vpWidth and vpHeight are the canvas-dimensions (640 * 480). the projection matrix is passed to the vertex-shader and multiplied with the model-view-matrix and the vertex-position. i played around with the zoom-factor. the more i zoom in the bigger the gaps are.
[Update 2]
okay. i investigated this a little more. bad zeppelin had a good hint. box2d has gaps between bodies to avoid tunneling. though this is not the complete explanation. i looked at the debug-draw-code - it is not resizing anything. i made a little test, zooming in both in webgl and for the debug draw with the following result:
with 10-times-zoom both have the same gap, but in "normal" zoom webgl is drawing bigger gaps than canvas 2d. what could be the explanation? my guess is anti-aliasing, which is enabled for canvas 2d, but not for webgl (i am using firefox - guess i'll make a chrome test later today to see what happens)
If you check the box2d manual, it says on the chapter 4.2 that the box2d engine keeps the polygons slightly separated to avoid tunneling. Checking the Box2d debug drawing code to see how they translate from box2d to draw coordinates might be a good idea to see how you could do the same in your app.
With the matrix you provided, you'll be creating a viewport that has a "virtual size" of twice your canvas dimensions. If you are trying for a pixel-for-pixel match, try this (with a zoom of 1.0):
mat4.ortho(-(this.vpWidth/2) * this.zoom, (this.vpWidth/2) * this.zoom, -(this.vpHeight/2) * this.zoom, (this.vpHeight/2) * this.zoom, 0.1, 100.0, this.pMatrix);
That way your 640*480 canvas will have extents of [-320,-240] to [320*240], which gives you 640*480 units total. Note that this will probably not eliminate the gaps entirely, since as bad zeppelin noted box2d puts them there intentionally, but it should make them less visible.
Another option to reduce the visible gaps is to draw your geometry scaled up just a bit from the physical representation, so that it displays with an extra pixel or two around the edges. The worst that may happen is that the geometry might appear to overlap just a bit, but it's up to you to determine if that's a more objectionable artifact than the gaps.

Resources