Exclude round rectangle from clipping region? - windows

What's the correct way to exclude a round rectangle from the clipping gregion with Delphi / GDI?
There is ExcludeClipRect to exclude a rectangular region and there is CreateRoundRectRgn together with SelectClipRgn to set the clipping region to a round rectangle.
But how can I exclude a round rectange from the clipping region (something like ExcludeClipRoundRect or ExcludeClipRgn)? I experimented with CombineRgn but did not get it working.

Thanks to the comment by #TLama I was able to solve it like this:
Region := CreateRectRgn (0, 0, ClientWidth, ClientHeight);
ExcludedRegion := CreateRoundRectRgn (1, 1, ClientWidth - 1, ClientHeight - 1, 3, 3);
CombineRgn (Region, Region, ExcludedRegion, RGN_XOR);
SelectClipRgn (Canvas.Handle, Region);
The problem before was that the region passed as the first parameter to CombineRgn has not been created. One sentence from the linked tutorial provided the clue:
One more thing to point out is that the destination region in
CombineRgn can be one of the source regions.
together with this information from MSDN:
hrgnDest [in]: A handle to a new region with dimensions defined by combining two
other regions. (This region must exist before CombineRgn is called.)

As an alternative to the already given answer, which will allow to define one less region, is to use ExtSelectClipRgn:
ExcludedRegion := CreateRoundRectRgn (1, 1, ClientWidth - 1, ClientHeight - 1, 3, 3);
ExtSelectClipRgn(Canvas.Handle, ExcludedRegion, RGN_DIFF);
If you're not sure that the clipping region has been unmodified before or not, and want to reset the region, you can call
SelectClipRgn(Canvas.Handle, 0);
before calling ExtSelectClipRgn.

Related

BufferGeometryUtils.mergeVertices - seems not to merge all identical vertices in three.js

I have a weird issues with BufferGeometryUtils.mergeVertices method
I took a simple cube from a jsfiddle and performed the mergeVertices and it seems mergeVertices does not merge all identical vertices as it should. See https://jsfiddle.net/tomfree/vpdwmycn/
E.g. the vertices given in the indexGeometry returned by mergeVertices are
Index 0 = (-1, -1, 1, )
index 1 = (1, -1, 1,)
index 2= (-1, 1, 1, )
index 3= (1, 1, 1,)
index 4= (1, -1, 1)
i.e. vertices at position 1 and 4 seem to be the same but shouldn't after mergeVertices to my understanding. I am pretty sure that I am missing sth. Can someone point me into the right direction?
Cheers
Tom
ps: Also posted as https://discourse.threejs.org/t/buffergeometryutils-mergevertices-seems-not-to-merge-all-identical-vertices/33890 in three.js forum
The merge process is functioning as expected. If you look at the count of each attribute of the original geometry you'll get 36, but if you look at the count of each attribute of the merged indexedGeo, you'll get 24:
console.log(geometry.getAttribute("position").count); // 36
console.log(indexedGeo.getAttribute("position").count); // 24
The problem you're encountering is that the merge method looks at all attributes before merging. In your case, position, normal, uv. The corners of a box have 3 vertices, each with its own normal pointing in 3 directions (one pointing up, one right, and one forward, for example). Since each vertex contains unique normal data on how to render its respective face, these vertices cannot be merged. Even though their position is the same, the other attributes are different.

Halcon - find edge position, draw line and lineintersection

I'm starting from scratch with Halcon, and I'm not able to solve a problem. I have a Object, need to extract edges from this object, draw a line along the borders and draw a point on the intersection of the lines.
I've tried tresholding, edge, color edge, but It extracts borders everywhere, except the ones I need..
Its just a test i am doing as it is similar to what I have to do later on a real project. But in two days I didnt manage to solve it..
Here is the base image, and the desired result image:
what I have so far:
open_framegrabber ('GigEVision', 0, 0, 0, 0, 0, 0, 'default', -1, 'default', -1, 'false', 'default', 'S1204667', 0, -1, AcqHandle)
set_framegrabber_param (AcqHandle, 'Gain', 1.0)
set_framegrabber_param (AcqHandle, 'ExposureTime', 20000)
set_framegrabber_param (AcqHandle, 'timerDuration', 1)
set_framegrabber_param (AcqHandle, 'BalanceWhiteAuto', 'Off')
set_framegrabber_param (AcqHandle, 'BalanceRatioSelector', 'Red')
set_framegrabber_param (AcqHandle, 'BalanceRatio', 1.22)
set_framegrabber_param (AcqHandle, 'BalanceRatioSelector', 'Green')
set_framegrabber_param (AcqHandle, 'BalanceRatio', 1.00)
set_framegrabber_param (AcqHandle, 'BalanceRatioSelector', 'Blue')
set_framegrabber_param (AcqHandle, 'BalanceRatio', 1.95)
grab_image (Image, AcqHandle)
threshold (Image, Region, 0, 128)
expand_region (Region, Region, RegionExpanded, 15, 'image')
close_framegrabber (AcqHandle)
Based off the original poster being worried about positional movement, I'm posting another answer which is more involved. This strategy might not be the easiest for this case but it is a general strategy that works for a lot of cases. Typically problems like this are solved as follows:
1) Perform a rough location of the part. This usually involves either a blob detection or a matching strategy (correlation, shape based etc). The output of this step is a transformation describing the location of the object (translation, orientation).
2) Based off the found location in step 1, the search regions for detecting features (lines, holes etc) are transformed or updated to new locations. Or the entire image is transformed.
I couldn't post all the code since it was too large. You will have to personal message me if you want me to email you the full HDevelop script. Here are some snippets to give you an idea:
Step 1: Threshold the image and setup search regions where the lines should be found. Only posting code for the first two regions but code is identical for the other three
threshold(Image, RegionThreshold, 0, 100)
region_to_bin(RegionThreshold, ImageBinary, 255, 0, Width, Height)
dev_display(ImageBinary)
*Use the mouse to draw region 1 around first line. Right click when finished.
draw_rectangle2(WindowHandle, Reg1Row, Reg1Column, Reg1Phi, Reg1Length1, Reg1Length2)
gen_rectangle2(Rectangle1, Reg1Row, Reg1Column, Reg1Phi, Reg1Length1, Reg1Length2)
*Use the mouse to draw region 2 around second line. Right click when finished.
draw_rectangle2(WindowHandle, Reg2Row, Reg2Column, Reg2Phi, Reg2Length1, Reg2Length2)
gen_rectangle2(Rectangle2, Reg2Row, Reg2Column, Reg2Phi, Reg2Length1, Reg2Length2)
The search regions look like this:
Step 2: Calculate the intersection of the lines. Only posting code for the first two lines but code is identical for the other three
*get line segment 1
reduce_domain(ImageBinary, Rectangle1, ImageReduced)
edges_sub_pix (ImageReduced, EdgesLine1, 'lanser2', 0.1, 20, 40)
fit_line_contour_xld (EdgesLine1, 'regression', -1, 0, 5, 2, RowBeginLine1, \
ColBeginLine1, RowEndLine1, ColEndLine1, Nr, Nc, Dist)
*get line segment 2
reduce_domain(ImageBinary, Rectangle2, ImageReduced)
edges_sub_pix (ImageReduced, EdgesLine2, 'lanser2', 0.1, 20, 40)
fit_line_contour_xld (EdgesLine2, 'regression', -1, 0, 5, 2, RowBeginLine2, \
ColBeginLine2, RowEndLine2, ColEndLine2, Nr, Nc, Dist)
*Calculate and display intersection line 1 to line 2
intersection_lines(RowBeginLine1, ColBeginLine1, RowEndLine1, ColEndLine1, \
RowBeginLine2, ColBeginLine2, RowEndLine2, ColEndLine2, \
Line1Line2IntersectRow, Line1Line2IntersectCol,
IsOverlappingLine1Line2)
This produces the following output:
Step 3: Create a normalized cross correlation model for finding the object when it undergoes translation or rotation. Here I choose a simple region on the bottom
gen_rectangle1 (ModelRegion, 271.583, 200, 349.083, 530)
reduce_domain (ImageBinary, ModelRegion, TemplateImage)
create_ncc_model (TemplateImage, 'auto', rad(0), rad(360), 'auto', 'use_polarity',
ModelID)
area_center (ModelRegion, ModelRegionArea, RefRow, RefColumn)
Output Image
Step 4: Now we consider what happens when the object is moved. To simulate this I warped the image using a affine transform. I then searched for the normalized cross correlation model created in step 3. Below you can see the object was found. The output is a row, column and angle where it was found. This is converted to a matrix called AlignmentHomMat2D
Some of the code:
threshold(TransImage, RegionThreshold, 0, 100)
region_to_bin(RegionThreshold, ImageBinaryScene, 255, 0, Width, Height)
* Matching 01: Find the model
find_ncc_model (ImageBinaryScene, ModelID, rad(0), rad(360), 0.8, 1, 0.5, 'true', 0,
Row, Column, Angle, Score)
* Matching 01: Display the centers of the matches in the detected positions
dev_display (TransImage)
set_line_width(WindowHandle, 3)
for I := 0 to |Score| - 1 by 1
* Matching 01: Display the center of the match
gen_cross_contour_xld (TransContours, Row[I], Column[I], 20, Angle)
dev_set_color ('green')
dev_display (TransContours)
hom_mat2d_identity (AlignmentHomMat2D)
hom_mat2d_translate (AlignmentHomMat2D, -RefRow, -RefColumn, AlignmentHomMat2D)
hom_mat2d_rotate (AlignmentHomMat2D, Angle[I], 0, 0, AlignmentHomMat2D)
hom_mat2d_translate (AlignmentHomMat2D, Row[I], Column[I], AlignmentHomMat2D)
* Matching 01: Display the aligned model region
affine_trans_region (ModelRegion, RegionAffineTrans, AlignmentHomMat2D,
'nearest_neighbor')
dev_display (RegionAffineTrans)
endfor
The output is as follows:
Step 5: Finally the search regions for locating the original lines are updated based off where the cross-correlation model was found.
Here is the code. Again I'm only showing the first two line segments:
*transform initial search regions
affine_trans_region(Rectangle1, Rectangle1Transformed,
AlignmentHomMat2D,'nearest_neighbor')
affine_trans_region(Rectangle2, Rectangle2Transformed,
AlignmentHomMat2D,'nearest_neighbor')
*get line segment 1
reduce_domain(ImageBinaryScene, Rectangle1Transformed, ImageReduced)
edges_sub_pix (ImageReduced, EdgesLine1, 'lanser2', 0.5, 20, 40)
fit_line_contour_xld (EdgesLine1, 'regression', -1, 0, 5, 2, RowBeginLine1, \
ColBeginLine1, RowEndLine1, ColEndLine1, Nr, Nc, Dist)
*get line segment 2
reduce_domain(ImageBinaryScene, Rectangle2Transformed, ImageReduced)
edges_sub_pix (ImageReduced, EdgesLine2, 'lanser2', 0.5, 20, 40)
fit_line_contour_xld (EdgesLine2, 'regression', -1, 0, 5, 2, RowBeginLine2, \
ColBeginLine2, RowEndLine2, ColEndLine2, Nr, Nc, Dist)
*Calculate and display intersection line 1 to line 2
intersection_lines(RowBeginLine1, ColBeginLine1, RowEndLine1, ColEndLine1, \
RowBeginLine2, ColBeginLine2, RowEndLine2, ColEndLine2, \
Line1Line2IntersectRow, Line1Line2IntersectCol,
IsOverlappingLine1Line2)
This produces the following output:
Halcon has a lot of ways this can be accomplished depending on the requirements. One of the most common techniques for detecting lines is to use the Hough Transform. I've attached a small HDevelop script showing how to get the intersection of two of the lines in your image. The same principle can be used for the others.
One of the most important concepts in Halcon is Regions. The example program first allows you to create two regions by drawing rectangles over top of two of the lines. The regions are black in the image below. On line 8 of the program (draw_rectangle2...) you will need to draw a bounding box around the first line. Right click when you are finished. Line 10 (draw rectangle2...) will expect you to draw a bounding box around the second line. Again right click when finished.
The regions are then combined on lines 13-16 by concatenation. On line 19 (reduce_domain) the domain of the image is reduced to the concatenated regions. You can think of this as a mask. Now when we search for the lines we will only search the part of the image where we created the regions.
emphasized text
read_image (Image, 'C:/Users/Jake/Documents/Stack Overflow/Halcon/Find Edge Position,
Draw Line and Line Intersection/FMuX1.jpg')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display(Image)
*Use the mouse to draw region 1 around first line. Right click when finished.
draw_rectangle2(WindowHandle, Reg1Row, Reg1Column, Reg1Phi, Reg1Length1, Reg1Length2)
*Use the mouse to draw region 2 around second line. Right click when finished.
draw_rectangle2(WindowHandle, Reg2Row, Reg2Column, Reg2Phi, Reg2Length1, Reg2Length2)
*Generate a single region to search for two lines
gen_rectangle2(Rectangle1, Reg1Row, Reg1Column, Reg1Phi, Reg1Length1, Reg1Length2)
gen_rectangle2(Rectangle2, Reg2Row, Reg2Column, Reg2Phi, Reg2Length1, Reg2Length2)
concat_obj(Rectangle1, Rectangle2, Regions)
union1(Regions, RegionUnion)
*Reduce the domain of the image to the region created in lines 13-16
reduce_domain(Image, RegionUnion, ImageReduced)
* Detect edges (amplitude) using the Sobel operator
sobel_amp (ImageReduced, EdgeAmplitude1, 'thin_sum_abs', 3)
dev_set_color ('red')
threshold (EdgeAmplitude1, Region1, 100, 255)
hough_lines (Region1, 4, 50, 5, 5, Line1Angle, Line1Dist)
dev_set_color ('blue')
* Store input lines described in HNF
gen_region_hline (LineRegions, Line1Angle, Line1Dist)
*Select Line1
select_obj(LineRegions, Line1, 1)
*Select Line2
select_obj(LineRegions, Line2, 2)
*Calculate and display intersection
intersection(Line1, Line2, Line1Line2Intersection)
area_center(Line1Line2Intersection, Line1Line2IntersectArea, Line1Line2IntersectRow,
Line1Line2IntersectCol)
disp_circle (WindowHandle, Line1Line2IntersectRow, Line1Line2IntersectCol, 6)

D3.js breaking up overlapping shapes

I'm trying to create a chart, where the input is a list of circles (position and radius) (or better ellipses) and the overlaps of the circles become shapes and a mouseover event can be applied. I also wish for the circles to move to the front, and have a mouseover effect, almost exactly like this
http://benfred.github.io/venn.js/examples/intersection_tooltip.html
The size of the overlap does not need to be known.
I've tried using D3.js Venn diagrams by Ben Frederickson. Although I can't understand some of the chart(selection) function, I've made it so that the circles can be inputted, and are drawn fine, including the overlaps, but this still relies on having the 'data' as an input as well and all of the sets (seen in the jsonp file) are still require. I realise that I can just make a script to list all of the possible sets, but this is ideal.
http://www.benfrederickson.com/venn-diagrams-with-d3.js/
I'm struggling to understand how the code creates these overlaps and then assigns them to the set.
Cheers, Ryan
Each intersection area has an SVG path computed for it by the 'venn.intersectionAreaPath' function. It takes a list of circles and returns a path element for the intersection area.
If you already have positions for the circles, you can override the 'layoutFunction' attribute on the venn diagram object like:
var circles = [{'x' : 0, 'y': 100, 'radius' : 80},
{'x' : 0, 'y': 0, 'radius' : 90 },];
var chart = venn.VennDiagram().layoutFunction(function() { return circles; });
d3.select("#venn").datum([{sets: [0]}, {sets:[1]}, {sets:[0,1]}]).call(chart);
This still requires having a list of all possible regions that you wish to draw (like "[{sets: [0]}, {sets:[1]}, {sets:[0,1]}]"), but this way you don't need to specify sizes for the regions.

Polygon decomposition in special direction

I am searching for a library which can do the decomposition of polygons. I want define define directions or lines in which the polygon should be fragmented, as seen here:
So that I get the small polygons. Anyone know a library which supports this?
Or any ideas?
I'm not sure which language are you using. I have a library, written for my purposes, that can get a full partition by given line set and return polygons as a result. It is written on PHP and called dimension and, using it, you can solve your question like way:
Define your polygon by a set of lines LineSet_2D or a Polygon_2D
Define partition lines also through Line_2D
Use LineSet_2D method getPolygons to find all polygons
I've written an example:
//define or polygon. Note that Polygon_2D can also be used
$rPolygon = new LineSet_2D(
new Line_2D( 0, 3, 1, 1),
new Line_2D( 1, 1, 3, 0),
new Line_2D( 3, 0, 1,-1),
new Line_2D( 1,-1, 0,-3),
new Line_2D( 0,-3,-1,-1),
new Line_2D(-1,-1,-3,0),
new Line_2D(-3, 0,-1, 1),
new Line_2D(-1, 1, 0, 3)
);
//define partition line set
$rPartition = new LineSet_2D(
new Line_2D(-1, 1, 1,-1),
new Line_2D(-1,-1, 1, 1)
);
//result line set:
$rResultSet = LineSet_2D::createFromArray(array_merge(
$rPolygon->getLines(),
$rPartition->getLines()
));
//for example, dump plain result:
var_dump($rResultSet->getPolygons());
You can also find this example here But I think it is not exact solution for your question, since my LineSet_2D class will return all looped polygons (i.e. not only 'pieces').
You are looking for a "polygon chop" boolean operation. You may google it for resources available.
Some queues on doing this on your own..
For each slicing line..
Find the intersection points of the slicing line with the edges of the polygon.
For each edge that it intersects, split the edge into two.
Split the polygon corresponding to the splitted edge, into two polygons.
Do the same for all polygons.
You will have to take care of special cases, like splitting line going through vertex and so on...

Translation and rotation around center

I'm trying to achieve something simple: Set a translation on X axis, and rotate the object around it's center by a fixed angle.
To achieve this, as far my current knowledge, it's necessary to move the object to the center, rotate, and move back to the original position. Okay. The problem I get although, is that it looks like the object rotate it's local axis and do the last translation along these axis, so it ends in a wrong position.
This is my code:
public void draw(GL10 gl) {
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);
gl.glTranslatef(x, 0, 0);
gl.glTranslatef(-x, 0, 0);
gl.glRotatef(-80, 0, 1, 0);
gl.glTranslatef(x, 0, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES10.GL_UNSIGNED_SHORT, indicesBuffer);
}
Before the rotation the object should be at 0,0,0. It rotates correctly. But then it comes near to the screen as if the x axis would be pointing to me (80°).
Note: I let only "opengl" as tag, since this is a general OpenGL question, the answer should not be Android related.
This is the deprecated way of doing this, but I guess that is no excuse for not answering the question.
OpenGL performs matrices multiplications in reverse order if multiple transforms are applied to a vertex. For example, If a vertex is transformed by MA first, and transformed by MB second, then OpenGL performs MB x MA first before multiplying the vertex. So, the last transform comes first and the first transform occurs last in your code.
gl.glPushMatrix();
gl.glTranslatef(globalX, 0, 0);
gl.glTranslatef(localX, 0 ,0);
gl.glRotatef(-80, 0, 1, 0);
gl.glTranslatef(-globalX, 0, 0);
gl.glPopMatrix();
First move from where you are in a hierarchy of transforms to the origin.
Then rotate around that origin.
Apply some local movement along any axis.
Move the object back to its global positioning.
Use glPushMatrix() and glPopMatrix() to undo changes for elements in the same level of relative positioning, this is having the same parent element to which they are relatively positioned.
The push preserves translations from previous (parent) objects that OpenGL applies after operations in the local code above, as it is the order of a common stack (LIFO), in this case the matrix stack.

Resources