I'm creating a CC3PlaneNode (cocos3d) with code that looks something like this:
CC3PlaneNode *bnode = [CC3PlaneNode nodeWithName: name];
CC3Texture *texture = [CC3Texture textureFromFile: texName];
[bnode populateAsCenteredRectangleWithSize: sz
andTessellation: ccg(1, 1)
withTexture: texture
invertTexture: YES];
bnode.material.specularColor = kCCC4FLightGray;
bnode.material.emissionColor = kCCC4FWhite;
bnode.material.isOpaque = NO;
bnode.shouldCullBackFaces = NO;
bnode.isTouchEnabled = YES;
bnode.location = loc;
[bnode retainVertexLocations];
Under certain circumstances, I'd like the plane to display the mirror image of its texture (a la the Flip Horizontal feature on many image programs.) I don't just want to flip the plane, itself, because that would throw out-of-position all of it's child-nodes, which is undesirable behaviour.
That is, if X & Y are parts of my texture, and "c" and "c'" are child-nodes in this diagram:
+--------+
| |
| x y |
| |
+--------+
c c'
after the flip, I want things to look like this:
+--------+
| |
| y x |
| |
+--------+
c c'
Other than not wanting to rotate/spin/flip the plane, itself, I'm otherwise pretty flexible on a solution.
Any hints?
Thanks!
Related
Given the following custom types:
type player = Orange | Red | Blue | White ;;
type piece = Knight of player | Town of player | City
of player | Road of player | Wool of player |
Brick of player | Lumber of player | Grain of
player | Ore of player ;;
All four players pieces are stored in a single piece array. Write functions
getplayer : piece -> player = <fun> that given a piece, it returns the
player that owns it.
# getplayer ( Town Orange ) ;;
- : player = Orange
# getplayer ( Wool Red ) ;;
- : player = Red
I'm trying to do it in a long way since It's the only one thats working for me. I did try pattern matching and putting for example | (_ Blue) -> Blue but I'm getting either two of the errors, value is piece but unit is expected or It's giving a syntax error at getplayer (Knight Blue);; at the first bracket when I call the function. I was just wondering if there are any faster ways to do this? Also, when I put first if instruction to return empty bracket if it receives empty brackets, I get an error that the type is wrong.
type player = Orange | Red | Blue | White ;;
type piece = Knight of player | Town of player | City
of player | Road of player | Wool of player |
Brick of player | Lumber of player | Grain of
player | Ore of player ;;
let rec getplayer = fun value ->
if value = (Knight Orange) then Orange
else if value = (Knight Red) then Red
else if value = (Knight Blue) then Blue
else if value = (Knight White) then White
else if value = (Town Orange) then Orange
else if value = (Town Red) then Red
else if value = (Town Blue) then Blue
else White;;
getplayer (Knight Blue) ;;
Pattern matching:
let rec getplayer = fun value -> match value with
| (_ Orange) -> Orange
| (_ Red) -> Red
| (_ Blue) -> Blue
| (_ White) -> White;;
getplayer (Knight Blue) ;;
When I try to pattern like this, my any value _ is obviously wrong notated or not placed at the right position since I always get the error
Syntax error: ')' expected
This '(' might be unmatched
I wanted to have (anything Color) and then return just that color since the player doesnt realy matter.
I also don't understand how to write the empty piece in a way that If you get () it returns () as well.
You seem to be asking whether there's a faster way to calculate your function. The answer is yes, it's faster to do a pattern match than a series of if tests. OCaml excels at compiling its pattern matches into efficient code.
If you give us an example where you can't get pattern matching to work, we can suggest how to fix it. I don't really want to write your code for you, as this is obviously an assignment.
For your second question, the type of () is unit. The type of (Knight Orange) (say) is piece. They aren't the same type at all. So that's what the compiler is telling you.
Update
You're trying to use a pattern of the form (_ Orange). But OCaml patterns don't work like that (as you know). You can't have a wild card for just the value constructor (like Knight), since in general the values inside the constructors can be of different types.
Instead of enumerating all the players, you can enumerate all the pieces:
let getplayer piece =
match piece with
| Knight p
| Town p
| City p
| Road p
| Wool p
| Brick p
| Lumber p
| Grain p
| Ore p -> p
Since every piece has a player, it might be better to structure them like this:
type player = Orange | Red | Blue | White
type piece_t =
| Knight | Town | City | Road | Wool
| Brick | Lumber | Grain | Ore
type piece = piece_t * player
I.e., you can have a piece represented by a pair.
Then you can write your function like this:
let getplayer (piecet, player) = player
I am new to image processing. We have a requirement to get circle centers with sub pixel accuracy from an image. I have used median blurring to reduce the noise. A portion of the image is shown below. The steps I followed for getting circle boundaries is given below
Reduced the noise with medianBlur
Applied OTSU thresholding with threshold API
Identified circle boundaries with findContours method.
I get different results when used different kernel size for medianBlur. I selected medianBlur to keep edges. I tried kernel size 3, 5 and 7. Now I am confused to use the right kernel size for medianBlur.
How can I decide the right kernel size?
Is there any scientific approach to decide the right kernel size for medianBlur?
I will give you two suggestions here for how to find the centroids of these disks, you can pick one depending on the level of precision you need.
First of all, using contours is not the best method. Contours depend a lot on which pixels happen to fall within the object on thresholding, noise affects these a lot.
A better method is to find the center of mass (or rather, the first order moments) of the disks. Read Wikipedia to learn more about moments in image analysis. One nice thing about moments is that we can use pixel values as weights, increasing precision.
You can compute the moments of a binary shape from its contours, but you cannot use image intensities in this case. OpenCV has a function cv::moments that computes the moments for the whole image, but I don't know of a function that can do this for each object separately. So instead I'll be using DIPlib for these computations (I'm an author).
Regarding the filtering:
Any well-behaved linear smoothing should not affect the center of mass of the objects, as long as the objects are far enough from the image edge. Being close to the edge will cause the blur to do something different on the side of the object closest to the edge compared to the other sides, introducing a bias.
Any non-linear smoothing filter has the ability to change the center of mass. Please avoid the median filter.
So, I recommend that you use a Gaussian filter, which is the most well-behaved linear smoothing filter.
Method 1: use binary shape's moments:
First I'm going to threshold without any form of blurring.
import diplib as dip
a = dip.ImageRead('/Users/cris/Downloads/Ef8ey.png')
a = a(1) # Use green channel only, simple way to convert to gray scale
_, t = dip.Threshold(a)
b = a<t
m = dip.Label(b)
msr = dip.MeasurementTool.Measure(m, None, ['Center'])
print(msr)
This outputs
| Center |
- | ----------------------- |
| dim0 | dim1 |
| (px) | (px) |
- | ---------- | ---------- |
1 | 18.68 | 9.234 |
2 | 68.00 | 14.26 |
3 | 19.49 | 48.22 |
4 | 59.68 | 52.42 |
We can now apply a smoothing to the input image a and compute again:
a = dip.Gauss(a,2)
_, t = dip.Threshold(a)
b = a<t
m = dip.Label(b)
msr = dip.MeasurementTool.Measure(m, None, ['Center'])
print(msr)
| Center |
- | ----------------------- |
| dim0 | dim1 |
| (px) | (px) |
- | ---------- | ---------- |
1 | 18.82 | 9.177 |
2 | 67.74 | 14.27 |
3 | 19.51 | 47.95 |
4 | 59.89 | 52.39 |
You can see there's some small change in the centroids.
Method 2: use gray scale moments:
Here we use the error function to apply a pseudo-threshold to the image. What this does is set object pixels to 1 and background pixels to 0, but pixels around the edges retain some intermediate value. Some people refer to this as a "fuzzy thresholding". These two images show the normal ("hard") threshold, and the error function clip ("fuzzy threshold"):
By using this fuzzy threshold, we retain more information about the exact (sub-pixel) location of the edges, which we can use when computing the first order moments.
import diplib as dip
a = dip.ImageRead('/Users/cris/Downloads/Ef8ey.png')
a = a(1) # Use green channel only, simple way to convert to gray scale
_, t = dip.Threshold(a)
c = dip.ContrastStretch(-dip.ErfClip(a, t, 30))
m = dip.Label(a<t)
m = dip.GrowRegions(m, None, -2, 2)
msr = dip.MeasurementTool.Measure(m, c, ['Gravity'])
print(msr)
This outputs
| Gravity |
- | ----------------------- |
| dim0 | dim1 |
| (px) | (px) |
- | ---------- | ---------- |
1 | 18.75 | 9.138 |
2 | 67.89 | 14.22 |
3 | 19.50 | 48.02 |
4 | 59.79 | 52.38 |
We can now apply a smoothing to the input image a and compute again:
a = dip.Gauss(a,2)
_, t = dip.Threshold(a)
c = dip.ContrastStretch(-dip.ErfClip(a, t, 30))
m = dip.Label(a<t)
m = dip.GrowRegions(m, None, -2, 2)
msr = dip.MeasurementTool.Measure(m, c, ['Gravity'])
print(msr)
| Gravity |
- | ----------------------- |
| dim0 | dim1 |
| (px) | (px) |
- | ---------- | ---------- |
1 | 18.76 | 9.094 |
2 | 67.87 | 14.19 |
3 | 19.50 | 48.00 |
4 | 59.81 | 52.39 |
You can see the differences are smaller this time, because the measurement is more precise.
In the binary case, the differences in centroids with and without smoothing are:
array([[ 0.14768417, -0.05677508],
[-0.256 , 0.01668085],
[ 0.02071882, -0.27547569],
[ 0.2137167 , -0.03472741]])
In the gray-scale case, the differences are:
array([[ 0.01277204, -0.04444567],
[-0.02842993, -0.0276569 ],
[-0.00023144, -0.01711335],
[ 0.01776011, 0.01123299]])
If the centroid measurement is given in µm rather than px, it is because your image file contains pixel size information. The measurement function will use this to give you real-world measurements (the centroid coordinate is w.r.t. the top-left pixel). If you do not desire this, you can reset the image's pixel size:
a.SetPixelSize(1)
The two methods in C++
This is a translation to C++ of the code above, including a display step to double-check that the thresholding produced the right result:
#include "diplib.h"
#include "dipviewer.h"
#include "diplib/simple_file_io.h"
#include "diplib/linear.h" // for dip::Gauss()
#include "diplib/segmentation.h" // for dip::Threshold()
#include "diplib/regions.h" // for dip::Label()
#include "diplib/measurement.h"
#include "diplib/mapping.h" // for dip::ContrastStretch() and dip::ErfClip()
int main() {
auto a = dip::ImageRead("/Users/cris/Downloads/Ef8ey.png");
a = a[1]; // Use green channel only, simple way to convert to gray scale
dip::Gauss(a, a, {2});
dip::Image b;
double t = dip::Threshold(a, b);
b = a < t; // Or: dip::Invert(b,b);
dip::viewer::Show(a);
dip::viewer::Show(b); // Verify that the segmentation is correct
dip::viewer::Spin();
auto m = dip::Label(b);
dip::MeasurementTool measurementTool;
auto msr = measurementTool.Measure(m, {}, { "Center"});
std::cout << msr << '\n';
auto c = dip::ContrastStretch(-dip::ErfClip(a, t, 30));
dip::GrowRegions(m, {}, m, -2, 2);
msr = measurementTool.Measure(m, c, {"Gravity"});
std::cout << msr << '\n';
// Iterate through the measurement structure:
auto it = msr["Gravity"].FirstObject();
do {
std::cout << "Centroid coordinates = " << it[0] << ", " << it[1] << '\n';
} while(++it);
}
I need to describe in Standard-ML a language made of properties and values. My property system is made of properties which can have values, like for example:
color: red | yellow | blue | transparent
align: left | center | right
bgcolor: red | yellow | blue | transparent
I created this sml file which tries to describe these properties:
datatype colorvalue = Transparent
| Yellow
| Blue
| Red
datatype bgcolorvalue = Transparent
| Yellow
| Blue
| Red
datatype alignvalue = Left
| Center
| Right
(* Generic property: it can be any of the above *)
datatype property = Color of colorvalue
| BgColor of bgcolorvalue
| Align of alignvalue
(* Some values *)
val prop1: property = Color Transparent
val prop2: property = BgColor Transparent
When I compile this in MoscowML I get:
,File "c:\Users\myuser\documents\myproj\property.sml", line 21, characters 31-42:
! val prop1: property = Color Transparent
! ^^^^^^^^^^^
! Type clash: expression of type
! bgcolorvalue
! cannot have type
! colorvalue
My guess
So I think that the problem is that color and bgcolor share a common property value: transparent which reflects in datatypes colorvalue and bgcolorvalue to share constructor Transparent. Actually they share all values, thus all constructors.
Is it the reason for this failure?
In any case, what should I do to describe my system?
It is easy to see that trying to use the same constructor in different types in the same scope would create problems with type inference. For example, what should the type of
fun heat Transparent = Yellow
| heat Yellow = Red
| heat Red = Blue
| heat Blue = Blue;
be? colorvalue ->colorvalue or bgbcolorvalue -> bgbcolorvalue or colorvalue -> bgbcolorvalue or bgbcolorvalue -> colorvalue?
The easiest workaround would be to adopt different naming conventions for the constructors. You could also use structures (which is how SML keeps e.g. different uses of the name map in the basis library without any clashes). Something like:
structure Color = struct
datatype value = Transparent
| Yellow
| Blue
| Red
end
structure BGBColor = struct
datatype value = Transparent
| Yellow
| Blue
| Red
end;
Then you can do things like:
- val a = Color.Transparent;
val a = Transparent : Color.value
- val b = BGBColor.Transparent;
val b = Transparent : BGBColor.value
This last was run in the SML/NJ REPL and illustrates how there are now no clashes.
i am trying to cast a void** pointer to an int** 2D array in C
here is the code that i am trying to work with (with all the extraneous bits removed):
\*assume that i have a data structure called graph with some
*element "void** graph" in it and some element "int order" */
void initialise_graph_data(graph_t *graph)
{
void **graph_data = NULL;
int (*matrix)[graph->order];
size_t size = (graph->order * graph->order) * sizeof(int);
graph_data = safe_malloc(size); /*safe malloc works fine*/
matrix = (int(*)[graph->order])graph_data;
graph->graph = graph_data;
}
when i compile that, it works fine, but gives me a warning that variable 'matrix' is set but not used. i dont really want to have to use the interim matrix variable because the function is just supposed to initialise the array, not put anything in it; but if i try to cast graph_data directly to an int** when i am assiging it to graph->graph like so:
graph->graph = (int(*)[graph->order])graph_data;
it gives me an assignment from incompatible pointer type warning.
am i just not casting it properly? does anyone have any suggestions as to how i can make it work without the interim "matrix" variable? or if not, what i can do with that variable so that it doesnt give me the warning that it is set but not used?
thanks
The compiler is right, an array of arrays (or a pointer to an array) is not the same as a pointer to a pointer. Just think about how they would be laid out in memory:
A matrix of size MxN in the form of an array of arrays:
+--------------+--------------+-----+----------------+--------------+-----+------------------+
| matrix[0][0] | matrix[0][1] | ... | matrix[0][N-1] | matrix[1][0] | ... | matrix[M-1][N-1] |
+--------------+--------------+-----+----------------+--------------+-----+------------------+
A and the same "matrix" in the form of pointer to pointer:
+-----------+-----------+-----------+-----+
| matrix[0] | matrix[1] | matrix[2] | ... |
+-----------+-----------+-----------+-----+
| | |
| | V
| | +--------------+--------------+-----+
| | | matrix[2][0] | matrix[2][1] | ... |
| | +--------------+--------------+-----+
| |
| V
| +--------------+--------------+-----+
| | matrix[1][0] | matrix[1][1] | ... |
| +--------------+--------------+-----+
|
V
+--------------+--------------+-----+
| matrix[0][0] | matrix[0][1] | ... |
+--------------+--------------+-----+
It doesn't matter if you allocate the correct size, the two variables simply are incompatible which is what your compiler is telling you.
I have a sprite class which I am working on making a function for collision. I want the function to return true if two sprites collide. When I call the function I pass the moving objects desired X and Y position along with it's height and width. The invoking sprite is the object I that I would like to check. For example if I wanted to check if player 1's move will intersect player 2's sprite I would say Player2.Collide(p1X, p1Y, p1H, p1W).
bool Sprite::Collides(int x, int y, unsigned short w, unsigned short h) const
{
if ((x == this->GetWidth() + this->GetLeft()) &&
(y >= this->GetTop() && y <= this->GetTop() + this->GetHeight()) ||
((x + w) == this->GetLeft()) &&
(y >= this->GetTop() && y <= this->GetTop() + this->GetHeight()))
return true;
else if ( (y == this->GetHeight() + this->GetTop()) &&
((x >= this->GetLeft() && x <= this->GetLeft() + this->GetWidth()) ||
((y + h) == this->GetTop() && (x >= this->GetLeft() && x <= this->GetLeft() + this->GetWidth()))))
return true;
return false;
}
The sprites are always rectangles. It seems I am forgetting to check some conditions for my collision. If the rectanges collide perfectly then everything works, however if I shift one up then try to butt against the other, it will glide right through. It seems each direction I approach has a similar behavior where it will work only for certain sections. Can you guys help me find what I'm forgetting to check?
I think you need to check the logic of your actual conditions again, shouldn't
(x == this->GetWidth() + this->GetLeft())
just that part of your if statement create a collision? right after that you have an &&. So in this case it needs to be touching on the top AND right, not just the right OR the top???
I also think the above line should really be:
(x <= this->GetWidth() + this->GetLeft())
Also, depending on your actual movement conditions (i.e. velocity, etc...) the above condition could really be
(x <= this->GetWidth() + this->GetLeft() - 1)
Lets explain the minus 1:
If you have two objects, one moving directly upward, and another moving directly downward, i.e. vertically and parallel to one another, then GetWidth + GetLeft creates a "went by" each other condition not a collision condition.
Example Sprites each 4 x 4 moving VERTICALLY with respect to each other:
Sprite A # (0, 2) Sprite B # (4, 2)
0 1 2 3 0 1 2 3
------------------------- -------------------------
| | | | | | | | | |
------------------------- -------------------------
| | | | | | | | | |
------------------------- -------------------------
| | | | | | | | | |
------------------------- -------------------------
| | | | | | | | | |
------------------------- -------------------------
Sprite A # (0, 1) Sprite B # (4, 3)
0 1 2 3
-------------------------
| | | | |
-------------------------
| | | | | 0 1 2 3
------------------------- -------------------------
| | | | | | | | | |
------------------------- -------------------------
| | | | | | | | | |
------------------------- -------------------------
| | | | |
-------------------------
| | | | |
-------------------------
Sprite A # (0, 0) Sprite B # (4, 4)
0 1 2 3
-------------------------
| | | | |
-------------------------
| | | | |
-------------------------
| | | | |
-------------------------
| | | | | 0 1 2 3
------------------------- -------------------------
| | | | |
-------------------------
| | | | |
-------------------------
| | | | |
-------------------------
| | | | |
-------------------------
When sprite a is at location (0, 0), then GetWidth + GetLeft = (0 + 4) which is RIGHT of the actual end of the sprite. IF another sprite is moving completely vertically downward with x position 4, then you algorithm would flag that as a collision, when in reality they are simply moving VERY CLOSELY by one another. This is where the - 1 comes in.
Also, you really want to make sure to be careful with your screen geometry. What I mean by this is many screens move from top-left being pixel (0, 0) to bottom right being pixel (positive X, positive y). Your second condition:
(y >= this->GetTop() && y <= this->GetTop() + this->GetHeight())
MIGHT need to be:
( (y + h - 1) >= this->GetTop() || y <= (this->GetTop() + this->GetHeight() - 1) )
The first portion needs to change because originally you were testing for the TOP of your input object colliding with the TOP of your object to be tested against. What you really want is the BOTTOM of your input to be tested with the TOP of your object to be tested against.
One thing I have always found extremely useful when trying to perform this type of coding, is to actually draw out very simple sketches with actual pixel based example numerics so that I can visualize it prior to coding it.
I hope all of this helps :-)