I am working to convert my CCScrollLayer.cpp code into more of a CCPicker code. In CCScrollLayer, I've defined a baselayer (CCColorLayer) to hold all of the menu objects. I also have a border that holds the ScrollLayer (using glScissor) called "overlay" that I want to be completely static.
In Objective C:
...
self.baseLayer = [CCLayerColor layerWithColor:(ccColor4B){150,150,150,0} width:s.width height:imgSize.height * numPages];
for (int i=0; i < [arrayPages count]; i++) {
CCNode* n = arrayPages[i];
n.position = ccp(s.width/2, s.height/2 + i * (imgSize.height + padding));
[baselayer addChild:n];
}
baseLayer.position = ccp(-s.width/2, -s.height/2 - s.height * currentPage);
[self addChild:baselayer];
...
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint n = [self convertTouchToNodeSpace:touch];
baselayer.position = ccp(touchStartedbaseLayerPosition.x, touchStartedbaseLayerPosition.y + n.y - touchStartedPoint.y);
}
In C++
...
overlay=new CCSprite();
overlay->initWithFile("overlay.png");
overlay->setPosition(ccp(300,300));
overlay->autorelease();
CCLayerColor* baselayer = new CCLayerColor();
baselayer->initWithColor(ccc4(255, 255, 255,255));
baselayer->setOpacity(255);
baselayer->setContentSize(CCSizeMake(s.width/10, (layers->count()*scrollWidth)));
baselayer->setPosition(s.width*.41,300);
baselayer->autorelease();
// Loop through the array and add the screens
unsigned int i;
for (i=0; i<layers->count(); i++)
{
CCLayer* l = static_cast<CCLayer*>(layers->objectAtIndex(i));
l->setAnchorPoint(ccp(0,0));
l->setPosition(ccp(s.width/40,(i*scrollWidth)));
baselayer->addChild(l);
}
this->addChild(baselayer,1);
this->addChild(overlay,1);
...
void CCScrollLayer::ccTouchMoved(CCTouch *touch, CCEvent *withEvent)
{
CCPoint touchPoint = touch->getLocation(); // Get the touch position
touchPoint = this->getParent()->convertToNodeSpace(touchPoint);
baselayer->setPosition(ccp(0,(-(currentScreen-1)*scrollWidth)+(touchPoint.y-startSwipe)));
}
I'm not sure what I'm doing wrong, but as soon as I try to start scrolling, I get a fatal error in the touchdispatcher
case CCTOUCHMOVED:
pHandler->getDelegate()->ccTouchMoved(pTouch, pEvent);
I'm guessing I'm missing something simple here. Can you point me in the write direction?
Related
How can the landmarks for hands be accessed in the Android version of MediaPipe? (Java)
I'd like to access the joints' positions in space.
A similar project that someone else has done in Python is available.
https://github.com/GasbaouiMohammedAlAmin/Finger-Counter-using-Hand-Tracking-And-Open-cv
The landmarks seem to be from the "solutions" part of the library.
I have a sample of code that works for Android, but it seems that all the processing is done without ever giving the landmarks to the Java file. https://github.com/jiuqiant/mediapipe_multi_hands_tracking_aar_example Is the base code of my project.
From that file, getMultiHandLandmarksDebugString takes in NormalizedLandmarkList, but how can those landmarks be accessed normally in the program?
import com.google.mediapipe.formats.proto.LandmarkProto.NormalizedLandmark;
Here the result is the object of HandsResults
To get the landmark position of each points i have used a list of normalizedlandmark type
List<NormalizedLandmark> ll = result.multiHandLandmarks().get(0).getLandmarkList();
The list size will be 21 to access those i have created a loop
for (int i = 0; i < ll.size(); i++)
For getting x, y and z of each of 21 landmarks
int x = (int) (ll.get(i).getX() * 1280);
Multiplied by 1280 texture width to get the pixel value
Here is the sample code u can check it out for more reference follow this link
List<NormalizedLandmark> ll = result.multiHandLandmarks().get(0).getLandmarkList();
Log.d("check", String.valueOf(ll.get(0).getX()));
for (int i = 0; i < ll.size(); i++) {
int x = (int) (ll.get(i).getX() * 1280);
int y = (int) (ll.get(i).getY() * 720);
// Log.d("chec1", String.valueOf(i)+" "+String.valueOf(x)+" "+String.valueOf(y));
for (int tip : finger_tips) {
Log.d("chec1", String.valueOf(tip) + " " + String.valueOf((int) (ll.get(tip).getX() * 1280)) + " " + String.valueOf((int) (ll.get(tip).getY() * 720)));
if ((ll.get(tip).getX() * 1280) < (ll.get(tip - 3).getX() * 1280)) {
finger_fold_status.add(false);
} else {
finger_fold_status.add(true);
}
}
int r = (int) (ll.get(thumb_tip-1).getY()*1280);
if(((int)ll.get(thumb_tip).getY()*1280)<r && r< (ll.get(thumb_tip-2).getY()*1280)){
if(finger_fold_status.contains(true)){
Log.d("res","LIke");
is = true;
runOnUiThread(new Runnable() {
#Override
public void run() {
tv.setText(R.string.like);
}
});
}
}if(((int)ll.get(thumb_tip).getY()*1280)>r && r>(ll.get(thumb_tip-2).getY()*1280)){
if(finger_fold_status.contains(true)){
Log.d("res1","DisLIke");
is = false;
runOnUiThread(new Runnable() {
#Override
public void run() {
tv.setText(R.string.dislike);
}
});
}
}
Log.d("stat", String.valueOf(finger_fold_status));
}
game.batch.begin();
for (Array obstacle_array123: obstacle_array) {
body = obstacle_array123;
for (Body bodies: body) {
if (bodies.getUserData() instanceof Array && bodies.isActive()) {
sprites_array = (Array)bodies.getUserData();
for (int fix_pos = 0; fix_pos < sprites_array.size; fix_pos++) {
sprite = sprites_array.get(fix_pos);
if (verts.size != 0) verts.removeRange(0, verts.size - 1);
f = bodies.getFixtureList().get(fix_pos);
s = (PolygonShape)f.getShape();
transform = bodies.getTransform();
for (int i = 0; i < s.getVertexCount(); i++)
{
s.getVertex(i, tmp);
transform.mul(tmp);
verts.add(new Vector2(tmp));
}
rotation_point.set((verts.get(0).x + verts.get(1).x + verts.get(2).x + verts.get(3).x) / 4, (verts.get(0).y + verts.get(1).y + verts.get(2).y + verts.get(3).y) / 4);
sprite.setPosition(rotation_point.x - sprite.getWidth() / 2, rotation_point.y - sprite.getHeight() / 2);
sprite.setRotation(bodies.getAngle() * MathUtils.radiansToDegrees);
sprite.draw(game.batch);
}
}
}
}
game.batch.end();
I have a game where my bodies are made from multiple square fixtures, so this is the code to render each square sprite on each square fixture.
2 problems - 1.st --> it only renders the first sprite in the array
2.nd --> if you look at the following loop (SOLVED)
for (int i = 0; i < s.getVertexCount(); i++)
{
s.getVertex(i, tmp);
transform.mul(tmp);
verts.add(new Vector2(tmp));
}
well it is apperantly different compared to
for (int i = 0; i < s.getVertexCount(); i++)
{
s.getVertex(i, tmp);
transform.mul(tmp);
verts.add(tmp);
}
The spawned coordinates in 2nd example are wrong for half width and half height of the square.
When I try to get the coordinated from both examples the numbers are the same, but when setting the sprite position, 2nd example goes off.
You should probably ask both questions separately, but to answer your second question, then they ARE different.
In the first one you add a new Vector2 to verts each time through the loop. So verts will end up holding a load of different Vector2's.
In the second one you add the same Vector2 to verts over and over again, so it will just have one Vector2 with the same value over and over again (remember Java is pass by reference).
Caveat - My answer assumes that verts is some sort of standard collection or a libgdx Array.
I'm trying to deal with ECG signal processing in android. I want to implement simple digital filters (lowpass, highpass)
I've got a transfer function:
here is what i've found:
wikipedia - lowpass filter - it looks quite easy here.
for i from 1 to n
y[i] := y[i-1] + α * (x[i] - y[i-1])
but there is nothing about transfer function which I want to use.
I also found the following matlab code
%% Low Pass Filter H(z) = (1 - 2z^(-6) + z^(-12)) / (1 - 2z^(-1) + z^(-2))
b = [1 0 0 0 0 0 -2 0 0 0 0 0 1];
a = [1 -2 1];
h_l = filter(b,a,[1 zeros(1,12)]);
ecg_l = conv (ecg ,h_l);
but there is no function like filter and conv in java (or I missed something).
Also I was looking on stackoverflow for an answer. But I didn't found anything about transfer function.
so can someone help me? I just want to move on with my project.
Given a time-domain recurrence equation (such as the one you quoted from wikipedia), the corresponding transfer function in the z-domain can relatively easily be obtained by using the following properties:
Where X(z) and Y(z) are the z-transforms of the time-domain input sequence x and output sequence y respectively.
Going the other way around, given a transfer function which can be expressed as a ratio of polynomials in z, such as:
the recurrence equation of the transfer function can be written as:
There are of course many different ways to implement such a recurrence equation, but a simple filter implementation following the Direct Form II would be along the line of:
// Implementation of an Infinite Impulse Response (IIR) filter
// with recurrence equation:
// y[n] = -\sum_{i=1}^M a_i y[n-i] + \sum_{i=0}^N b_i x[n-i]
public class IIRFilter {
public IIRFilter(float a_[], float b_[]) {
// initialize memory elements
int N = Math.max(a_.length, b_.length);
memory = new float[N-1];
for (int i = 0; i < memory.length; i++) {
memory[i] = 0.0f;
}
// copy filter coefficients
a = new float[N];
int i = 0;
for (; i < a_.length; i++) {
a[i] = a_[i];
}
for (; i < N; i++) {
a[i] = 0.0f;
}
b = new float[N];
i = 0;
for (; i < b_.length; i++) {
b[i] = b_[i];
}
for (; i < N; i++) {
b[i] = 0.0f;
}
}
// Filter samples from input buffer, and store result in output buffer.
// Implementation based on Direct Form II.
// Works similar to matlab's "output = filter(b,a,input)" command
public void process(float input[], float output[]) {
for (int i = 0; i < input.length; i++) {
float in = input[i];
float out = 0.0f;
for (int j = memory.length-1; j >= 0; j--) {
in -= a[j+1] * memory[j];
out += b[j+1] * memory[j];
}
out += b[0] * in;
output[i] = out;
// shift memory
for (int j = memory.length-1; j > 0; j--) {
memory[j] = memory[j - 1];
}
memory[0] = in;
}
}
private float[] a;
private float[] b;
private float[] memory;
}
which you could use to implement your specific transfer function like so:
float g = 1.0f/32.0f; // overall filter gain
float[] a = {1, -2, 1};
float[] b = {g, 0, 0, 0, 0, 0, -2*g, 0, 0, 0, 0, 0, g};
IIRFilter filter = new IIRFilter(a, b);
filter.process(input, output);
Note that you can alternatively also factorize the numerator and denominator into 2nd order polynomials and obtain a cascade of 2nd order filters (known as biquad filters).
I'm looking for a way to manage Info Windows (open, close, set content) for polygons, just like it's done for markers
I can probably listen for onClick event and put a some hidden marker there and open an InfoWindow for that marker. There is a problem finding a polygon to retrieve an InfoWindow content though.
There is a more elegant solution?
I have been working out in a solution similar to your problem.
As you said, the main problem is how to get if LatLng coordinate got from OnMapLongClickListener() is inside a polygon.
There is a popular algorithm you can use for doing this called Point-in-polygon algorithm.. This is a adaptation for Java of this algorithm.
private boolean containsInPolygon(LatLng latLng, Polygon polygon) {
boolean oddTransitions = false;
List<VerticesPolygon> verticesPolygon = polygon.getVertices();
float[] polyY, polyX;
float x = (float) (latLng.latitude);
float y = (float) (latLng.longitude);
// Create arrays for vertices coordinates
polyY = new float[verticesPolygon.size()];
polyX = new float[verticesPolygon.size()];
for (int i=0; i<verticesPolygon.size() ; i++) {
VerticesPolygon verticePolygon = verticesPolygon.get(i);
polyY[i] = (float) (verticePolygon.getVertice().getLongitude());
polyX[i] = (float) (verticePolygon.getVertice().getLatitude());
}
// Check if a virtual infinite line cross each arc of the polygon
for (int i = 0, j = verticesPolygon.size() - 1; i < verticesPolygon.size(); j = i++) {
if ((polyY[i] < y && polyY[j] >= y)
|| (polyY[j] < y && polyY[i] >= y)
&& (polyX[i] <= x || polyX[j] <= x)) {
if (polyX[i] + (y - polyY[i]) / (polyY[j] - polyY[i])
* (polyX[j] - polyX[i]) < x) {
// The line cross this arc
oddTransitions = !oddTransitions;
}
}
}
// Return odd-even number of intersecs
return oddTransitions;
}
Finally, create a CustomInfoWindowsAdapter for managing what you want to show.
I am working on Wi-Engine and currently facing the issue while loading two sheets into zwoptex manager.
In the code below I am loading two sheets (sheeta and sheetb), with two animations which are stored as actions in class (firstAction, secondAction). Later when I runAction on the sprite on button click, the firstAction runs fine but the secondAction uses the texture of firstAction with frames of second, which causes unexpected result. kindly if you can let me know what I am missing or doing wrong.
`
/******** Loading Sheet 1********/
Texture2D tex = Texture2D.makePNG(R.drawable.sheeta);
ZwoptexManager.addZwoptex("sheeta", R.raw.sheeta, tex);
/******** Loading Sheet 2********/
Texture2D tex2 = Texture2D.makePNG(R.drawable.sheetb);
ZwoptexManager.addZwoptex("sheetb", R.raw.sheetb,tex2);
petSprite = ZwoptexManager.makeSprite("image_1.png"); // image_1 is in Sheeta
/******* Creating Animations and Actions ******/
Animation firstAnimation = new Animation(0);
for (int i = 1; i <= 9; i++)
{
firstAnimation.addFrame(0.1f, ZwoptexManager.getFrameRect("sheeta", "image_" + i + ".png"));
}
Animate a = (Animate)Animate.make(firstAnimation).autoRelease();
firstAction = (Action)Repeat.make(a, 2);
Animation secondAnimation = new Animation(0);
for (int i = 10; i <= 20; i++)
{
secondAnimation.addFrame(0.1f, ZwoptexManager.getFrameRect("sheetb",
"image_" + i + ".png"));
}
Animate b = (Animate)Animate.make(secondAnimation).autoRelease();
secondAction = (Action)Repeat.make(b, 1);
`
The following is the proper way to get animations working, for those who are having the same problem.
Animation secondAnimation = new Animation(0);
for (int i = 52; i <= 65; i++)
{
SpriteFrame temp = ZwoptexManager.getSpriteFrame("sheetb","image_" + i + ".png");
temp.setDuration(0.1f);
secondAnimation.addFrame(temp);
}
Animate temp = (Animate)Animate.make(secondAnimation).autoRelease();
Action firstAction = (Action)Repeat.make(temp, 1);