I want to track 2 colours, but only record the movement of those two colours and hide the video feed - colors

For context: I am going to analyze the breathing movement of parents during kangaroo mother care and I wish to respect their privacy by not recording them, but only the movement of stickers I placed on their chest and stomach.
So far, I'm able to track 2 colours based on webcam input through the code below. However, I would like to record only the tracked colours instead of the webcam feed as to preserve the privacy of the parent.
Does anybody know how to add a background colour, whilst still being able to track colour?
import processing.video.*;
Capture video;
final int TOLERANCE = 20;
float XRc = 0;// XY coordinate of the center of the first target
float YRc = 0;
float XRh = 0;// XY coordinate of the center of the second target
float YRh = 0;
int ii=0; //Mouse click counter
color trackColor; //The first color is the center of the robot
color trackColor2; //The second color is the head of the robot
void setup() {
size(640,480);
video = new Capture(this,640,480);
video.start();
trackColor = color(255,0,0);
trackColor2 = color(255,0,0);
smooth();
}
void draw() {
background(0);
if (video.available()) {
video.read();
}
video.loadPixels();
image(video,0,0);
float r2 = red(trackColor);
float g2 = green(trackColor);
float b2 = blue(trackColor);
float r3 = red(trackColor2);
float g3 = green(trackColor2);
float b3 = blue(trackColor2);
int somme_x = 0, somme_y = 0;
int compteur = 0;
int somme_x2 = 0, somme_y2 = 0;
int compteur2 = 0;
for(int x = 0; x < video.width; x++) {
for(int y = 0; y < video.height; y++) {
int currentLoc = x + y*video.width;
color currentColor = video.pixels[currentLoc];
float r1 = red(currentColor);
float g1 = green(currentColor);
float b1 = blue(currentColor);
if(dist(r1,g1,b1,r2,g2,b2) < TOLERANCE) {
somme_x += x;
somme_y += y;
compteur++;
}
else if(compteur > 0) {
XRc = somme_x / compteur;
YRc = somme_y / compteur;
}
if(dist(r1,g1,b1,r3,g3,b3) < TOLERANCE) {
somme_x2 += x;
somme_y2 += y;
compteur2++;
}
else if(compteur2 > 0) {
XRh = somme_x2 / compteur2;
YRh = somme_y2 / compteur2;
}
}
}
if(XRc != 0 || YRc != 0) { // Draw a circle at the first target
fill(trackColor);
strokeWeight(0.05);
stroke(0);
ellipse(XRc,YRc,20,20);
}
if(XRh != 0 || YRh != 0) {// Draw a circle at the second target
fill(trackColor2);
strokeWeight(0.05);
stroke(0);
ellipse(XRh,YRh,20,20);
}
}
void mousePressed() {
if (mousePressed && (mouseButton == RIGHT)) { // Save color where the mouse is clicked in trackColor variable
if(ii==0){
if (mouseY>480){mouseY=0;mouseX=0;}
int loc = mouseX + mouseY*video.width;
trackColor = video.pixels[loc];
ii=1;
}
else if(ii==1){
if (mouseY>480){mouseY=0;mouseX=0;}
int loc2 = mouseX + mouseY*video.width;
trackColor2 = video.pixels[loc2];
ii=2;
}
}
}

Try adding the background(0); right before you draw the first circle. It should cover the video and you can draw the circles on top of it.
Regards
Jose

Related

checking edge for circular movement

I want to make my dot program turn around when they reach edge
so basically i just simply calculate
x = width/2+cos(a)*20;
y = height/2+sin(a)*20;
it's make circular movement. so i want to make this turn around by checking the edge. i also already make sure that y reach the if condition using println command
class particles {
float x, y, a, r, cosx, siny;
particles() {
x = width/2; y = height/2; a = 0; r = 20;
}
void display() {
ellipse(x, y, 20, 20);
}
void explode() {
a = a + 0.1;
cosx = cos(a)*r;
siny = sin(a)*r;
x = x + cosx;
y = y + siny;
}
void edge() {
if (x>width||x<0) cosx*=-1;
if (y>height||y<0) siny*=-1;
}
}
//setup() and draw() function
particles part;
void setup(){
size (600,400);
part = new particles();
}
void draw(){
background(40);
part.display();
part.explode();
part.edge();
}
they just ignore the if condition
There is no problem with your check, the problem is with the fact that presumably the very next time through draw() you ignore what you did in response to the check by resetting the values of cosx and siny.
I recommend creating two new variables, dx and dy ("d" for "direction") which will always be either +1 and -1 and change these variables in response to your edge check. Here is a minimal example:
float a,x,y,cosx,siny;
float dx,dy;
void setup(){
size(400,400);
background(0);
stroke(255);
noFill();
x = width/2;
y = height/2;
dx = 1;
dy = 1;
a = 0;
}
void draw(){
ellipse(x,y,10,10);
cosx = dx*20*cos(a);
siny = dy*20*sin(a);
a += 0.1;
x += cosx;
y += siny;
if (x > width || x < 0)
dx = -1*dx;
if (y > height || y < 0)
dy = -1*dy;
}
When you run this code you will observe the circles bouncing off the edges:

Reaction-Diffusion algorithm on Processing + Multithreading

I have made an implementation of the Reaction-Diffusion algorithm on Processing 3.1.1, following a video tutorial. I have made some adaptations on my code, like implementing it on a torus space, instead of a bounded box, like the video.
However, I ran into this annoying issue, that the code runs really slow, proportional to the canvas size (larger, slower). With that, I tried optmizing the code, according to my (limited) knowledge. The main thing I did was to reduce the number of loops running.
Even then, my code still ran quite slow.
Since I have noticed that with a canvas of 50 x 50 in size, the algorithm ran at a good speed, I tried making it multithreaded, in such a way that the canvas would be divided between the threads, and each thread would run the algorithm for a small region of the canvas.
All threads read from the current state of the canvas, and all write to the future state of the canvas. The canvas is then updated using Processing's pixel array.
However, even with multithreading, I didn't see any performance improvement. By the contrary, I saw it getting worse. Now sometimes the canvas flicker between a rendered state and completely white, and in some cases, it doesn't even render.
I'm quite sure that I'm doing something wrong, or I may be taking the wrong approach to optimizing this algorithm. And now, I'm asking for help to understand what I'm doing wrong, and how I could fix or improve my code.
Edit: Implementing ahead of time calculation and rendering using a buffer of PImage objects has removed flickering, but the calculation step on the background doesn't run fast enough to fill the buffer.
My Processing Sketch is below, and thanks in advance.
ArrayList<PImage> buffer = new ArrayList<PImage>();
Thread t;
Buffer b;
PImage currentImage;
Point[][] grid; //current state
Point[][] next; //future state
//Reaction-Diffusion algorithm parameters
final float dA = 1.0;
final float dB = 0.5;
//default: f = 0.055; k = 0.062
//mitosis: f = 0.0367; k = 0.0649
float feed = 0.055;
float kill = 0.062;
float dt = 1.0;
//multi-threading parameters to divide canvas
int threadSizeX = 50;
int threadSizeY = 50;
//red shading colors
color red = color(255, 0, 0);
color white = color(255, 255, 255);
color black = color(0, 0, 0);
//if redShader is false, rendering will use a simple grayscale mode
boolean redShader = true;
//simple class to hold chemicals A and B amounts
class Point
{
float a;
float b;
Point(float a, float b)
{
this.a = a;
this.b = b;
}
}
void setup()
{
size(300, 300);
//initialize matrices with A = 1 and B = 0
grid = new Point[width][];
next = new Point[width][];
for (int x = 0; x < width; x++)
{
grid[x] = new Point[height];
next[x] = new Point[height];
for (int y = 0; y < height; y++)
{
grid[x][y] = new Point(1.0, 0.0);
next[x][y] = new Point(1.0, 0.0);
}
}
int a = (int) random(1, 20); //seed some areas with B = 1.0
for (int amount = 0; amount < a; amount++)
{
int siz = 2;
int x = (int)random(width);
int y = (int)random(height);
for (int i = x - siz/2; i < x + siz/2; i++)
{
for (int j = y - siz/2; j < y + siz/2; j++)
{
int i2 = i;
int j2 = j;
if (i < 0)
{
i2 = width + i;
} else if (i >= width)
{
i2 = i - width;
}
if (j < 0)
{
j2 = height + j;
} else if (j >= height)
{
j2 = j - height;
}
grid[i2][j2].b = 1.0;
}
}
}
initializeThreads();
}
/**
* Divide canvas between threads
*/
void initializeThreads()
{
ArrayList<Reaction> reactions = new ArrayList<Reaction>();
for (int x1 = 0; x1 < width; x1 += threadSizeX)
{
for (int y1 = 0; y1 < height; y1 += threadSizeY)
{
int x2 = x1 + threadSizeX;
int y2 = y1 + threadSizeY;
if (x2 > width - 1)
{
x2 = width - 1;
}
if (y2 > height - 1)
{
y2 = height - 1;
}
Reaction r = new Reaction(x1, y1, x2, y2);
reactions.add(r);
}
}
b = new Buffer(reactions);
t = new Thread(b);
t.start();
}
void draw()
{
if (buffer.size() == 0)
{
return;
}
PImage i = buffer.get(0);
image(i, 0, 0);
buffer.remove(i);
//println(frameRate);
println(buffer.size());
//saveFrame("output/######.png");
}
/**
* Faster than calling built in pow() function
*/
float pow5(float x)
{
return x * x * x * x * x;
}
class Buffer implements Runnable
{
ArrayList<Reaction> reactions;
boolean calculating = false;
public Buffer(ArrayList<Reaction> reactions)
{
this.reactions = reactions;
}
public void run()
{
while (true)
{
if (buffer.size() < 1000)
{
calculate();
if (isDone())
{
buffer.add(currentImage);
Point[][] temp;
temp = grid;
grid = next;
next = temp;
calculating = false;
}
}
}
}
boolean isDone()
{
for (Reaction r : reactions)
{
if (!r.isDone())
{
return false;
}
}
return true;
}
void calculate()
{
if (calculating)
{
return;
}
currentImage = new PImage(width, height);
for (Reaction r : reactions)
{
r.calculate();
}
calculating = true;
}
}
class Reaction
{
int x1;
int x2;
int y1;
int y2;
Thread t;
public Reaction(int x1, int y1, int x2, int y2)
{
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
}
public void calculate()
{
Calculator c = new Calculator(x1, y1, x2, y2);
t = new Thread(c);
t.start();
}
public boolean isDone()
{
if (t.getState() == Thread.State.TERMINATED)
{
return true;
} else
{
return false;
}
}
}
class Calculator implements Runnable
{
int x1;
int x2;
int y1;
int y2;
//weights for calculating the Laplacian for A and B
final float[][] laplacianWeights = {{0.05, 0.2, 0.05},
{0.2, -1, 0.2},
{0.05, 0.2, 0.05}};
/**
* x1, x2, y1, y2 delimit a rectangle. The object will only work within it
*/
public Calculator(int x1, int y1, int x2, int y2)
{
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
//println("x1: " + x1 + ", y1: " + y1 + ", x2: " + x2 + ", y2: " + y2);
}
#Override
public void run()
{
reaction();
show();
}
public void reaction()
{
for (int x = x1; x <= x2; x++)
{
for (int y = y1; y <= y2; y++)
{
float a = grid[x][y].a;
float b = grid[x][y].b;
float[] l = laplaceAB(x, y);
float a2 = reactionDiffusionA(a, b, l[0]);
float b2 = reactionDiffusionB(a, b, l[1]);
next[x][y].a = a2;
next[x][y].b = b2;
}
}
}
float reactionDiffusionA(float a, float b, float lA)
{
return a + ((dA * lA) - (a * b * b) + (feed * (1 - a))) * dt;
}
float reactionDiffusionB(float a, float b, float lB)
{
return b + ((dB * lB) + (a * b * b) - ((kill + feed) * b)) * dt;
}
/**
* Calculates Laplacian for both A and B at same time, to reduce amount of loops executed
*/
float[] laplaceAB(int x, int y)
{
float[] l = {0.0, 0.0};
for (int i = x - 1; i < x + 2; i++)
{
for (int j = y - 1; j < y + 2; j++)
{
int i2 = i;
int j2 = j;
if (i < 0)
{
i2 = width + i;
} else if (i >= width)
{
i2 = i - width;
}
if (j < 0)
{
j2 = height + j;
} else if (j >= height)
{
j2 = j - height;
}
int weightX = (i - x) + 1;
int weightY = (j - y) + 1;
l[0] += laplacianWeights[weightX][weightY] * grid[i2][j2].a;
l[1] += laplacianWeights[weightX][weightY] * grid[i2][j2].b;
}
}
return l;
}
public void show()
{
currentImage.loadPixels();
//renders the canvas using the pixel array
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
float a = next[x][y].a;
float b = next[x][y].b;
int pix = x + y * width;
float diff = (a - b);
color c;
if (redShader) //aply red shading
{
float thresh = 0.5;
if (diff < thresh)
{
float diff2 = map(pow5(diff), 0, pow5(thresh), 0, 1);
c = lerpColor(black, red, diff2);
} else
{
float diff2 = map(1 - pow5(-diff + 1), 1 - pow5(-thresh + 1), 1, 0, 1);
c = lerpColor(red, white, diff2);
}
} else //apply gray scale shading
{
c = color(diff * 255, diff * 255, diff * 255);
}
currentImage.pixels[pix] = c;
}
}
currentImage.updatePixels();
}
}
A programmer had a problem. He thought “I know, I’ll solve it with threads!”. has Now problems. two he
Processing uses a single rendering thread.
It does this for good reason, and most other renderers do the same thing. In fact, I don't know of any multi-threaded renderers.
You should only change what's on the screen from Processing's main rendering thread. In other words, you should only change stuff from Processing's functions, not your own thread. This is what's causing the flickering you're seeing. You're changing stuff as it's being drawn to the screen, which is a horrible idea. (And it's why Processing uses a single rendering thread in the first place.)
You could try to use your multiple threads to do the processing, not the rendering. But I highly doubt that's going to be worth it, and like you saw, it might even make things worse.
If you want to speed up your sketch, you might also consider doing the processing ahead of time instead of in real time. Do all your calculations at the beginning of the sketch, and then just reference the results of the calculations when it's time to draw the frame. Or you could draw to a PImage ahead of time, and then just draw those.

Getting the dominant color in processing

im trying to get the most dominant color of an image (perfect case: getting the 5 dominant colors sorted by most used). Is there a way to make that in processing? I tried already a code i found but with that im only getting the average color:
color extractColorFromImage(PImage img)
{
img.loadPixels();
int r = 0, g = 0, b = 0;
for (int i=0; i<img.pixels.length; i++)
{
color c = img.pixels[i];
r += c>>16&0xFF;
g += c>>8&0xFF;
b += c&0xFF;
}
r /= img.pixels.length; g /= img.pixels.length; b /= img.pixels.length;
return color(r, g, b);
}
So its not really that what i need. I already read that i could do it with HSV, k-means and so on.... and any way to do it in processing?
Example: Here i want to get the color red as the dominant color, with the example above im getting a dark orange. Red-Blue Picture
What about this?
Set the image in a bitmap and analyze every pixel. Just add up the amount of times a pixel is in the image.
static Dictionary<Color, int> CalcImageColors(Bitmap image)
{
var frequency = new Dictionary<Color, int>();
for (var h = 0; h < image.Height; h++)
{
for (var w = 0; w < image.Width; w++)
{
var pixel = image.GetPixel(w, h);
if (frequency.ContainsKey(pixel))
{
frequency[pixel]++;
}
else
{
frequency.Add(pixel, 1);
}
}
}
return frequency.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
}
The RGB colour space may not always work as you'd expect in terms of mixing/averaging colours. You should convert to a perceptual colour space like CIE LAB. To do that you need to first convert from RGB to CIE XYZ then from CIE XYZ to CIE RGB. For more info check out these pages on CIE XYZ and CIE LAB.
In terms of Processing, here's a prototype using RGB<>CIE XYZ<>CIE LAB colour conversion code from this answer (with small tweaks to compile in the Processing IDE (which is antsy about using the static keyword)):
void setup(){
PImage src = loadImage("http://i.stack.imgur.com/0H1OM.png");
size(src.width*4,src.height);
noStroke();
//display original image
image(src,0,0);
//display RGB average color
fill(extractColorFromImage(src));
rect(src.width,0,src.width,src.height);
//display (perceptual)Lab average color
fill(extractAverageColorFromImage(src));
rect(src.width*2,0,src.width,src.height);
//display the most dominant colour
fill(extractDominantColorFromImage(src));
rect(src.width*3,0,src.width,src.height);
}
color extractDominantColorFromImage(PImage img){
//create a hashmap - the key is the colour, the value associated is the number of pixels per colour
HashMap<Integer,Integer> colorCounter = new HashMap<Integer,Integer>();
int numPixels = img.pixels.length;
for (int i=0; i<numPixels; i++){
int colorKey = img.pixels[i];
//if the colour has already been added to the hashmap, increment the count
if(colorCounter.containsKey(colorKey)){
colorCounter.put(colorKey,colorCounter.get(colorKey)+1);
}else{//otherwise count it as 1
colorCounter.put(colorKey,1);
}
}
//find the most dominant colour - note you can implement this to return more than one if you need to
int max = 0;//what's the highest density of pixels per one colour
int dominantColor = 0;//which colour is it
//for each key (colour) in the keyset
for(int colorKey : colorCounter.keySet()){
//get the pixel count per colour
int count = colorCounter.get(colorKey);
//if this one is the highest, updated the max value and keep track of the colour
if(count > max){
max = count;
dominantColor = colorKey;
}
}
//return the winner (colour with most pixels associated)
return dominantColor;
}
color extractColorFromImage(PImage img)
{
img.loadPixels();
int r = 0, g = 0, b = 0;
for (int i=0; i<img.pixels.length; i++)
{
color c = img.pixels[i];
r += c>>16&0xFF;
g += c>>8&0xFF;
b += c&0xFF;
}
r /= img.pixels.length; g /= img.pixels.length; b /= img.pixels.length;
return color(r, g, b);
}
color extractAverageColorFromImage(PImage img){
float[] average = new float[3];
CIELab lab = new CIELab();
int numPixels = img.pixels.length;
for (int i=0; i<numPixels; i++){
color rgb = img.pixels[i];
float[] labValues = lab.fromRGB(new float[]{red(rgb),green(rgb),blue(rgb)});
average[0] += labValues[0];
average[1] += labValues[1];
average[2] += labValues[2];
}
average[0] /= numPixels;
average[1] /= numPixels;
average[2] /= numPixels;
float[] rgb = lab.toRGB(average);
return color(rgb[0] * 255,rgb[1] * 255,rgb[2] * 255);
}
//from https://stackoverflow.com/questions/4593469/java-how-to-convert-rgb-color-to-cie-lab
import java.awt.color.ColorSpace;
public class CIELab extends ColorSpace {
#Override
public float[] fromCIEXYZ(float[] colorvalue) {
double l = f(colorvalue[1]);
double L = 116.0 * l - 16.0;
double a = 500.0 * (f(colorvalue[0]) - l);
double b = 200.0 * (l - f(colorvalue[2]));
return new float[] {(float) L, (float) a, (float) b};
}
#Override
public float[] fromRGB(float[] rgbvalue) {
float[] xyz = CIEXYZ.fromRGB(rgbvalue);
return fromCIEXYZ(xyz);
}
#Override
public float getMaxValue(int component) {
return 128f;
}
#Override
public float getMinValue(int component) {
return (component == 0)? 0f: -128f;
}
#Override
public String getName(int idx) {
return String.valueOf("Lab".charAt(idx));
}
#Override
public float[] toCIEXYZ(float[] colorvalue) {
double i = (colorvalue[0] + 16.0) * (1.0 / 116.0);
double X = fInv(i + colorvalue[1] * (1.0 / 500.0));
double Y = fInv(i);
double Z = fInv(i - colorvalue[2] * (1.0 / 200.0));
return new float[] {(float) X, (float) Y, (float) Z};
}
#Override
public float[] toRGB(float[] colorvalue) {
float[] xyz = toCIEXYZ(colorvalue);
return CIEXYZ.toRGB(xyz);
}
CIELab() {
super(ColorSpace.TYPE_Lab, 3);
}
private double f(double x) {
if (x > 216.0 / 24389.0) {
return Math.cbrt(x);
} else {
return (841.0 / 108.0) * x + N;
}
}
private double fInv(double x) {
if (x > 6.0 / 29.0) {
return x*x*x;
} else {
return (108.0 / 841.0) * (x - N);
}
}
// private Object readResolve() {
// return getInstance();
// }
// private static class Holder {
// static final CIELab INSTANCE = new CIELab();
// }
// private static final long serialVersionUID = 5027741380892134289L;
private final ColorSpace CIEXYZ =
ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
private final double N = 4.0 / 29.0;
}
You can see a preview bellow with the original image, then (in this order):
the RGB average
the LAB average
the most dominant colour
Break your problem down into smaller steps.
Step 1: Can you iterate over the pixels in the image? Check out the get() function to help with that. Or you can use the for loop in your code. But first, try just printing out the RGB value of each cell.
Step 2: When you have that working, try keeping track of the count of each color you see. The way you do this depends on exactly what you want to do: should (255, 0, 0) and (200, 0, 0) both count as red? But one way might be to use a HashMap<color, Integer> that keeps track of the count of each color.
Step 3: Given the counts of each color, now you can output the dominant color. How you do this depends on the data structure you used in step 2.
If you get stuck on a specific step, post an MCVE and we'll go from there. Good luck!
You might want to look at this tutorial on finding dominant colors in an image. - it's a more mathematical take on the problem. The idea is to use statistics on the image to figure out the main colors. Source code is available for OpenCV - so it should be possible to adapt it to use for Processing!

Why are these shapes the wrong color?

So I'm writing up a processing sketch to test a randomized terrain generator for a scorched earth clone I'm working on. It seems to work as intended but with one minor problem. In the code I generate 800 1 pixel wide rectangles and set the fill to brown beforehand. The combination of the rectangles should be a solid mass with a brown dirt-like color (77,0,0).
However, the combination shows up as black regardless of the rgb fill value set. I think it might have something to do with each rectangle's border being black? Does anyone know what is happening here offhand?
final int w = 800;
final int h = 480;
void setup() {
size(w, h);
fill(0,128,255);
rect(0,0,w,h);
int t[] = terrain(w,h);
fill(77,0,0);
for(int i=0; i < w; i++){
rect(i, h, 1, -1*t[i]);
}
}
void draw() {
}
int[] terrain(int w, int h){
width = w;
height = h;
//min and max bracket the freq's of the sin/cos series
//The higher the max the hillier the environment
int min = 1, max = 6;
//allocating horizon for screen width
int[] horizon = new int[width];
double[] skyline = new double[width];
//ratio of amplitude of screen height to landscape variation
double r = (int) 2.0/5.0;
//number of terms to be used in sine/cosine series
int n = 4;
int[] f = new int[n*2];
//calculating omegas for sine series
for(int i = 0; i < n*2 ; i ++){
f[i] = (int) random(max - min + 1) + min;
}
//amp is the amplitude of the series
int amp = (int) (r*height);
for(int i = 0 ; i < width; i ++){
skyline[i] = 0;
for(int j = 0; j < n; j++){
skyline[i] += ( sin( (f[j]*PI*i/height) ) + cos(f[j+n]*PI*i/height) );
}
skyline[i] *= amp/(n*2);
skyline[i] += (height/2);
skyline[i] = (int)skyline[i];
horizon[i] = (int)skyline[i];
}
return horizon;
}
I think it might have something to do with each rectangle's border being black?
I believe this is the case. In your setup() function, I added the noStroke() function before you draw the rectangles. This removes the black outline to the rectangles. Since each rectangle is only 1 pixel wide, having this black stroke (which is on by default) makes the color of each rectangle black, no matter what color you try to choose before.
Here is an updated setup() function - I now see a reddish brown terrain:
void setup() {
size(w, h);
fill(0, 128, 255);
rect(0, 0, w, h);
int t[] = terrain(w, h);
fill(77, 0, 0);
noStroke(); // here
for (int i=0; i < w; i++) {
rect(i, h, 1, -1*t[i]);
}
}

how to find touch position is inside the shape in box2d?

pls any one help me
i have create the edges in my project.i know how to check touch position is inside the shape
if (fix->TestPoint(locationWorld))
{
CCLOG(#"****touch inside shape***");
}
but i want create hexagon shape and i need to ball create inside hexagon shape and move inside hexagon.
i did ball move inside hexagon shape using below code:
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0, 0);
b2Body* groundBody = world->CreateBody(&groundBodyDef);
int countVal=[pos count];
// Define the ground box shape.
b2PolygonShape groundBox;
int range=[pos count]-2;
CCLOG(#"countVal=%d,range=%d",countVal,range);
for (int i=0; i<=range; i=i+2)
{
float x1,y1,x2,y2;
x1=[[pos objectAtIndex:i] floatValue];
y1=[[pos objectAtIndex:i+1] floatValue];
if (i==range)
{
x2=[[pos objectAtIndex:0] floatValue];
y2=[[pos objectAtIndex:1] floatValue];
}
else
{
x2=[[pos objectAtIndex:i+2] floatValue];
y2=[[pos objectAtIndex:i+3] floatValue];
}
CCLOG(#"x1=%f,y1=%f,x2=%f,y2=%f",x1,y1,x2,y2);
groundBox.SetAsEdge(b2Vec2(x1/PTM_RATIO,y1/PTM_RATIO),b2Vec2(x2/PTM_RATIO,y2/PTM_RATIO));
groundBody->CreateFixture(&groundBox, 0);
}
but i dont know how to find touch position is inside polygon shape.i use cocos2d with box2d
pls any one help me
Finally i got the answer:
i am checking if the point is inside polygon:
int pnpoly(int npol, float *xp, float *yp, float x, float y)
{
int i, j, c = 0;
for (i = 0, j = npol-1; i < npol; j = i++)
{
if ((((yp[i] <= y) && (y < yp[j])) ||
((yp[j] <= y) && (y < yp[i]))) &&
(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
c = !c;
}
return c;
}

Resources