How to plot the real-time graph using achartengine similar to oscilloscope - java

I am working with achartengine. I have to read a txt file and plot the graph. I get the graph plot. But, what I want to do is when the graph reaches the end of the layout view, it should get plotted from the beginning view as similar to oscilloscope view.
I want my graph exactly similar to the graph in this link
http://www.youtube.com/watch?v=N6BuRqeUhqc.
What I have done so far is:
private class ChartTask extends AsyncTask<Void, String, Void>{
String[] values = new String[2];int i1=0;
// Generates dummy data in a non-ui thread
#Override
protected Void doInBackground(Void... params) {
int i = 0;
try{
do{
values[0] = Integer.toString(i);
values[1] = Integer.toString(amplitude[i]);
if(i<=600){
multiRenderer.setXAxisMax(600);
}
else if(i>600){
double minX = amplitudeSeries.getMaxX();
multiRenderer.setXAxisMin(minX);
}
publishProgress(values);
Thread.sleep(1);
i++;
}while(i<=amplitude.length);}
catch (Exception e1){
}
return null;
}
Can someone help me with this. Thanks for anyone's help.

It should be quite easy to draw dynamic charts using AChartEngine. Just update the contents of your dataset and call chartView.repaint().

This is an animation task. Use Bitmap to hold the chart and use timer to plot periodically one X,Y pair per call into bitmap. After that, call invalidate() to repaint the bitmap on the screen of device.
The last thing you need is a trivial mod operation. Here are the possible code fragments of this periodically called code:
// Get position in bitmap from the iteration index
int ig = mIteration % bitmap.getWidth();
// Erase the vertical line in bitmap
for (int y = 0, y < bitmap.getHeight(); i++)
bitmap.setPixel(ig, y, Color.WHITE);
// Plot the point
bitmap.setPixel(ig, data[mIteration], Color.BLACK);
// Advance mIteration field value.
mIteration = (mIteration + 1) % data.length;
// Force to repaint component containing the bitmap.
invalidate();
this will care for you about returning the cursor back and repeating the animation after reaching the end of data.

Related

Java - Making ArrayList Values Rotate for Game

I have three global variables:
private PhysicsActor blade;
private PhysicsActor blades;
private ArrayList<PhysicsActors> blades;
I created an actor object from a class I created for my game.
blade = new PhysicsActor();
blade.storeAnimation( "", exTex );
blade.setOriginCenter();
blade.setEllipseBoundary();
blade.setMaxSpeed(50);
blade.setDeceleration(50);
bladesList = new ArrayList<PhysicsActor>();
for (int i = 0; i < 3 ; i++)
{
float xCoord = randomFloatGenerator(425, 50);
float yCoord = randomFloatGenerator(mapHeight - 200, 275);
blades = blade.clone();
blades.setPosition(xCoord, yCoord);
mainStage.addActor(blades);
bladesList.add(blades);
}
The problem is not that they do not spawn. It is that when I call for them to rotate while my game is running in my update(float dt) method, only one of them is rotating:
public void update(float dt)
{
// rotate the blade 70 degrees
blades.rotateBy(70);
// rest of code etc
}
Here is an image to help visualize
I know that this is happening because I am only rotating the blades actor. What I want to do is have them all rotate from the ArrayList. I do not know how to get them from the list however. I have tried bladesList.get(i) using a for loop and a couple other ways I saw online but it would not work. Any tips or instructions for me?
Also, I will post more code to clarify anything confusing if requested.
You can try this
for (PhysicsActor blade : bladesList) {
blade.rotateBy(70);
}
this will make all the blades in your list rotate by 70. Given you can access the array from where you are calling it.

Making canvas' drawline clickable

Based on this answer, I created a arrayList of rectF.
Technique to make a canvas drawLine() clickable?
here's the logic of my code :
List<RectF> rectFs;
Point pt1;
Point pt2;
then
path.moveTo(pt1.x, pt1.y);
path.lineTo(pt2.x, pt2.y);
path.computeBounds(rectF, true);
rectFs.add(rectF);
and then, I have this method to check the clicked and the rectF arrayList.
void lineHighighted(Point pt) {
int ct = 0;
for(RectF rectF : rectFs) {
if(rectF.contains(pt.x, pt.y)) {
ct++;
Log.d(tag, ct + "HERE");
}
}
}
my problem is, sometimes, the whole arraylist is selected or "called" even I didn't touch that "line".
Any wrong in my code?
Thanks in advance.
ADDITIONAL :
I found out that after adding this code in my canvas :
path.moveTo(coor1[0], coor1[1]);
path.lineTo(coor2[0], coor2[1]);
canvas.drawPath(path, paint2);
path.computeBounds(rectf, true);
my previous result :
it becomes like this :
It might be!Because i don't see your code of interaction with canvas ill post the code which fully working.The logic is that one line mustn't overlay another one in case to proper function.hope i could help you.
// setting where I will draw the ImageView for taking pictures
// rec is used for onInterceptTouchEvent. I pass this from the
// highest to lowest layer so that when this area of the screen
// is pressed, it ignores the TouchView events and passes it to
// this activity so that the button can be pressed.
rec.set((int)((double)mScreenWidth*.85),
(int)((double)mScreenHeight*.10) ,
(int)((double)mScreenWidth*.85)+mButtonDrawable.getMinimumWidth(),
(int)((double)mScreenHeight*.70)+mButtonDrawable.getMinimumHeight());
mButtonDrawable = null;
By This Logic you can use whatever you want in this logic it lets click happen not being overlaid

How can I make transparent background of a Bitmap?

I am working on a module in which I have to make background of bitmap image transparent. Actually, I am making an app like "Stick it" through which we can make sticker out of any image. I don't know from where to begin.
Can someone give me a link or a hint for it?
Original Image-
After making background transparent-
This is what I want.
I can only provide some hints on how to approach your problem. You need to do a Image Segmenation. This can be achived via the k-means algotithm or similar clustering algorithms. See this for algorithms on image segmantation via clustering and this for a Java Code example. The computation of the clustering can be very time consumeing on a mobile device. Once you have the clustering you can use this approach to distinguish between the background and the foreground. In general all you picture should have a bachground color which differs strongly from the foreground otherwise it is not possible for the clustering to distunguish between them. It can also happen that a pixel inside of you foreground is assigned to the cluster of the background beacuase it has a similar color like your background. To prevent this from happening you could use this approach or a region grwoth algorithm. Afterward you can let you user select the clusters via touch and remove them. I also had the same problems with my Android App. This will give you a good start and once you have implemented the custering you just need to tewak the k parameter of the clustering to get good results.
Seems like a daunting task. If you are talking about image processing if I may understand then you can try https://developers.google.com/appengine/docs/java/images/
Also if you want to mask the entire background ( I have not tried Stick it) the application needs to understand the background image map. Please provide some examples so that I can come up with more definitive answers
One possibility would be to utilize the floodfill operation in the openCV library. There are lots of examples and tutorials on how to do similar stuff to what you want and OpenCV has been ported to Android. The relevant terms to Google are of course "openCV" and "floodfill".
For this kind of task(and app) you'll have to use openGL. Usually when working on openGL you based your fragment shader on modules you build in Matlab. Once you have the fragment shader it's quite easy to apply it on image. check this guide how to do it.
Here's a link to remove background from image in MatLab
I'm not fully familiar with matlab and if it can generate GLSL code by itself(the fragment shader). But even if it doesn't - you might want to learn GLSL yourself because frankly - you are trying to build a graphics app and Android SDK is somehow short when using it for images manipulation, and most important is that without a strong hardware-acceleration engine behind it - I cannot see it works smooth enough.
Once you'll have the figure image - you can apply it on transparent background easily like this:
Canvas canvas = new Canvas(canvasBitmap);
canvas.drawColor(Color.TRANSPARENT);
BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.drawable.loading);
Bitmap yourBitmap = bd.getBitmap();
Paint paint = new Paint();
canvas.drawBitmap(yourBitmap, 0, 0, paint);
Bitmap newBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(),image.getConfig());
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(image, 0, 0, null);
OR
See this
hope this wll helps you
if you are working in Android you might need a Buffer to get the pixels from the image - it's a intBuffer and it reduces the memory usage enormously... to get data from and stor data into the Buffer you have three methods (you can skip that part if you don't have 'large' images):
private IntBuffer buffer;
public void copyImageIntoBuffer(File imgSource) {
final Bitmap temp = BitmapFactory.decodeFile(imgSource
.getAbsolutePath());
buffer.rewind();
temp.copyPixelsToBuffer(buffer);
}
protected void copyBufferIntoImage(File tempFile) throws IOException {
buffer.rewind();
Bitmap temp = Bitmap.createBitmap(imgWidth, imgHeight,
Config.ARGB_8888);
temp.copyPixelsFromBuffer(buffer);
FileOutputStream out = new FileOutputStream(tempFile);
temp.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
}
public void mapBuffer(final File tempFile, long size) throws IOException {
RandomAccessFile aFile = new RandomAccessFile(tempFile, "rw");
aFile.setLength(4 * size); // 4 byte pro int
FileChannel fc = aFile.getChannel();
buffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size())
.asIntBuffer();
}
now you can use the Buffer to get the pixels and modify them as desired... (i've copyied a code snipped that used a Progress bar on my UI and therefore needed a Handler/ProgressBar... when i did this i was working on bigger images and implemented a imageFilter (Gauss-Filter,Grey-Filter, etc.... just delete what is not needed)
public void run(final ProgressBar bar, IntBuffer buffer, Handler mHandler, int imgWidth, int imgHeight, int transparentColor ) {
for (int dy = 0; dy < imgHeight; dy ++){
final int progress = (dy*100)/imgHeight;
for (int dx = 0; dx < imgWidth; dx ++ ){
int px = buffer.get();
//int a = (0xFF000000 & px);
//int r = (0x00FF0000 & px) >> 16;
//int g = (0x0000FF00 & px) >> 8;
//int b = (0x000000FF & px);
//this makes the color transparent
if (px == transparentColor) {
px = px | 0xFF000000;
}
//r = mid << 16;
//g = mid << 8;
//b = mid;
//int col = a | r | g | b;
int pos = buffer.position();
buffer.put(pos-1, px);
}
// Update the progress bar
mHandler.post(new Runnable() {
public void run() {
bar.setProgress(progress);
}
});
}
}
if you really have small images, you can get the pixels directly during onCreate() or even better create a Buffer (maybe a HashMap or a List) before you start the Activity...

JAVA Background Animation (LinearGradientPaint)

A LinearGradientPaint object from java.awt may appear nice once painted, but there's a problem I'm having with it for painting an animated background in some kind of game model that's taking me long to build.
I want to paint an animated rainbow gradient on the background using the Graphics2D paint object, except that when I do so, I notice a lot of lag in repainting the panel. It should repaint itself at least 30 frames per second, which is only possible if the Paint object the graphics object uses is not a rainbow gradient.
Even running it as a separate thread will not do the trick. Below is the code for what I am trying to do at the end of each frame:
gamePanel.executor.execute(new Runnable(){
public void run()
{
while(true)
{
if (Background.selectedBackgroundIndex >= Background.SKY_HORIZON_GRADIENT_PAINT &&
Background.selectedBackgroundIndex < Background.SPACE_PAINT)
{
float displacementValue = 1.0f;
if (Background.backgroundShape.y < ((-2990.0f) + CannonShooterModel.gamePanel.getSize().height) && gamePanel.horizonGoingDown)
gamePanel.horizonGoingDown = false;
else if (Background.backgroundShape.y > (-10.0f) && !gamePanel.horizonGoingDown)
gamePanel.horizonGoingDown = true;
Point2D.Double startPoint = (Point2D.Double)(((LinearGradientPaint)Background.background).getStartPoint()),
endPoint = (Point2D.Double)(((LinearGradientPaint)Background.background).getEndPoint());
if (gamePanel.horizonGoingDown)
Background.backgroundShape.y -= displacementValue;
else
Background.backgroundShape.y += displacementValue;
startPoint.setLocation(0, Background.backgroundShape.y);
endPoint.setLocation(0, Background.horizonGradientPaintHeight + Background.backgroundShape.y);
// Should be done in another thread, particularly in arithmetic calculations.
Background.background = new LinearGradientPaint(startPoint, endPoint,
((LinearGradientPaint)Background.background).getFractions(),
((LinearGradientPaint)Background.background).getColors());
}
for (int a = 0; a < PlayerUnit.weapon.bullets.length; a++)
{
if (PlayerUnit.weapon.bullets[a] != null)
{
if (PlayerUnit.weapon instanceof Pistol &&
((Ellipse2D.Float)PlayerUnit.weapon.bullets[a]).x + ((Pistol)PlayerUnit.weapon).bulletWidth >= 0 &&
((Ellipse2D.Float)PlayerUnit.weapon.bullets[a]).x <= CannonShooterModel.gamePanel.getSize().width &&
((Ellipse2D.Float)PlayerUnit.weapon.bullets[a]).y + ((Pistol)PlayerUnit.weapon).bulletWidth >= 0)
{
if (PlayerUnit.weapon.weaponAngles[a] >= 0)
((Ellipse2D.Float)PlayerUnit.weapon.bullets[a]).x +=
PlayerUnit.weapon.bulletSpeed * Math.cos(PlayerUnit.weapon.weaponAngles[a]);
else
((Ellipse2D.Float)PlayerUnit.weapon.bullets[a]).x -=
PlayerUnit.weapon.bulletSpeed * Math.cos(PlayerUnit.weapon.weaponAngles[a]);
if (PlayerUnit.weapon.weaponAngles[a] >= 0)
((Ellipse2D.Float)PlayerUnit.weapon.bullets[a]).y -=
PlayerUnit.weapon.bulletSpeed * Math.sin(PlayerUnit.weapon.weaponAngles[a]);
else
((Ellipse2D.Float)PlayerUnit.weapon.bullets[a]).y +=
PlayerUnit.weapon.bulletSpeed * Math.sin(PlayerUnit.weapon.weaponAngles[a]);
}
else
PlayerUnit.weapon.bullets[a] = null;
}
}
//System.out.println(Background.backgroundShape.y);
repaint();
try
{
Thread.sleep(1000 / 60);
}
catch (InterruptedException ex)
{
}
}
}
});
The classes Background, PlayerUnit, and CannonShooterModel are important to my game model. It's an upright shooting game supposed to be designed with various weapons and enemies.
This rainbow gradient I have uses an array of eight different Color objects. For every frame passed through, I change the y-coordinate for both Point2D.Float objects required for the gradient paint as desired. In order for the animation to work, I have to actually instantiate another object of LinearGradientPaint again, with some of the previous properties from the previous object, and have it be referenced by the variable background of type Paint.
Problem is, LinearGradientPaint does not have a method to where you can do a translate on the two end points, and the get methods do not return the actual object that LinearGradientPaint object contains. (what I mean is, the get methods return a new object of Point2D with the same values as those part of the LinearGradientPaint object.)
For every frame passed, I have to change not only the y-coordinate property of the shape that's associated with the gradient, but also set the locations of the two Point2D objects that are needed to instantiate LinearGradientPaint once again.
I would love to re-explain this much simpler, because I can have trouble with some knowledge of English, even though this is my primary language. Please let me know if you need re-explanation.
There are a couple of solutions you might try.
Instead of filling the entire paintable area, you could create a BufferedImage whose width is 1 pixel and height equal to the area you want to fill (assuming you are fill vertically). You would then apply the LinearGradientPaint to this BufferedImage's Graphics2D and fill it (don't forget to dispose of the Graphics context when your done).
Then, you would simply use Graphics#drawImage(Image, x, y, width, height, ImageObserver) to actually paint the image. Generally speaking, it appears that it's faster to rescale an image then it is to fill it with a LinearGradientPaint, especially when you consider you are only stretching the image horizontally.
The other choice would be to generate a basic BufferedImage which had the LinearGradientPaint already applied and you would simply paint this offset as required. This would probably require you to paint it at least twice to allow it to "stitch" toegther...
If you are just making the background gradient move up and down, could you write it to an image at initialization and then move and wrap the image vertically?

programmatically edit images for puzzle usage

I'm making a sliding puzzle ( 3x3/4x4/5x5 with the lower-right corner cut out ). However I can't figure out where to start with programmatically cutting images ( which will be loaded from own gallery in sdcard or database from app ) in the puzzle pieces.
I've been looking over the internet and nothing really helped me.
What is the best way to cut up this image and store it in a new database (and still will be able to slide them)? Just a push in the right direction would be appreciated.
Check the PhotoGaffe app..
Its available on Google code here.
It allows user to choose between 3x3, 4x4, 5x5, and 6x6 puzzles.
This may help you in doing your task.
Straight from something I'm working on at the moment!
Bitmap main = BitmapFactory.decodeResource(getResources(), R.drawable.puzzle);
if( main.getHeight() > main.getWidth() ){
rescalefactor =((float)screenHeight)/main.getHeight();}
else {
rescalefactor = ( (float)screenWidth)/main.getWidth();
}
main = Bitmap.createScaledBitmap(main,(int)(main.getWidth()*rescalefactor),(int)(main.getHeight()*rescalefactor), false);
Bitmap cropped;
LinearLayout layout[] = new LinearLayout[rows];
int x=0,y=0,i=0,j=0,width=main.getWidth()/column,height=main.getHeight()/rows;
int count = 1;
for(i=0;i<rows;++i)
{
layout[i] = new LinearLayout(this);
for(j=0;j<column;++j)
{
cropped = Bitmap.createBitmap(main,x,y,width,height);
image[i][j] = new Tile(this);
image[i][j].setImageBitmap(cropped);
image[i][j].row =i;image[i][j].column =j;
image[i][j].setPadding(1, 1, 1, 1);
image[i][j].setOnClickListener(this);
image[i][j].setDrawingCacheEnabled(true);
image[i][j].setId(count); count++;
layout[i].addView(image[i][j]);
x += width;
}
x = 0; y += height;
root.addView(layout[i]);
}
This is the line where the work is really done:
cropped = Bitmap.createBitmap(main,x,y,width,height);
The Tile class is super simple. Just an extended ImageView with row and column fields:
public class Tile extends ImageView {
public int row, column;
public Tile(Context context)
{ super(context);}
}

Categories