I use this codes for draw a polygon on a canvas. But I want to calculate the area of polygon. Of course give the measurements of each line. I see a lot of example on maps but ı don't convert/adapt on canvas. Can anyone showing a way or method ?
Thanks in advance.
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(new DrawingView(MainActivity.this));
}
class DrawingView extends SurfaceView
{
private SurfaceHolder surfaceHolder;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private List<Point> pointsList = new ArrayList<Point>();
public DrawingView(Context context)
{
super(context);
surfaceHolder = getHolder();
paint.setColor(Color.BLACK);
paint.setStyle(Style.FILL);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
if (surfaceHolder.getSurface().isValid())
{
// Add current touch position to the list of points
pointsList.add(new Point((int) event.getX(), (int) event.getY()));
// Get canvas from surface
Canvas canvas = surfaceHolder.lockCanvas();
// Clear screen
canvas.drawColor(Color.WHITE);
// Iterate on the list
for (int i = 0; i < pointsList.size(); i++)
{
Point current = pointsList.get(i);
Point first = pointsList.get(0);
// Draw points
canvas.drawCircle(current.x, current.y, 5, paint);
// Draw line with next point (if it exists)
if (i + 1 < pointsList.size())
{
Point next = pointsList.get(i + 1);
canvas.drawLine(current.x, current.y, next.x, next.y, paint);
canvas.drawLine(next.x, next.y, first.x, first.y, paint);
c
}
}
// Release canvas
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
return false;
}
}
}
Here's a method for calculating the area of a polygon.
for (int i = 0; i < points.size(); i++) {
float addX = points.get(i).x;
float addY = points.get(i == points.size() - 1 ? 0 : i + 1).y;
float subX = points.get(i == points.size() - 1 ? 0 : i + 1).x;
float subY = points.get(i).y;
total += (addX * addY * 0.5);
total -= (subX * subY * 0.5);
}
return Math.abs(total);
Related
I found some code to draw line and now i wand drawing line progressively so that i cloud see it being drawn.
This is the code
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawLine(0, 0, 20, 20, paint);
canvas.drawLine(20, 0, 0, 20, paint);
}
}
How can i do that?
Tnx
Did you see that?
Look at source code ;)
http://www.curious-creature.com/2013/12/21/android-recipe-4-path-tracing/
You will want to break up your drawing into multiple steps. Inside your onDraw call, you will want to draw a part of your line, and update a variable so that the next line segment is drawn. Then you will want to make multiple onDraw() calls in an animation loop. You will need to be careful where you make your calls to the animation loop from. Read about the View class for more information, particular event handling and threading. http://developer.android.com/reference/android/view/View.html
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
float x1 = 0;
float x2 = 20;
float y1 = 0;
float y2 = 20;
public DrawView(Context context) {
super(context);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
if(doClear) {
//clear canvas to begin new animation
}
canvas.drawLine(x1, y1, x2, y2, paint);
}
public void animateLoop() {
while(x1 < 500) {
x1 += 20;
y1 += 20;
x2 += 20;
y2 += 20;
//tell android this view needs to be redrawn
invalidate();
}
//when done set doClear to true so
}
If you really want to learn about animation, you should start with something like this example: http://developer.android.com/guide/topics/graphics/drawable-animation.html.
I am developing mind mapping tool for android. Till now the objects are drawn on screen ontouch event. I want to create one main object and draw this type of lines from that object. The example is,
http://www.biggerplate.com/mapImages/xl/e666ca33-abf7-4cc7-acc9-4aea9487feef.png
Please Help.
This is the class to draw a node touch events
package com.example.mindmapping;
import java.util.LinkedList;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
public class CreateBitmap extends Activity {
Bitmap bitmap;
SurfaceHolder holder;
//LinkedList<newNode> nodes;
LinkedList<Node> nodes;
float x, y;
Node node;
Boolean collision;
SurfaceView surfaceView;
Context baseCtx;
//DrawMindMap dm;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
baseCtx = this.getBaseContext();
setContentView(R.layout.drawmindmap);
nodes = new LinkedList<Node>();
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rectangle_small);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
holder = surfaceView.getHolder();
surfaceView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("TOUCH", "On touch start, total nodes: " + String.valueOf(nodes.size()));
x = event.getX();
Log.d("XPOS", "touch x" + String.valueOf(x));
y = event.getY();
Log.d("YPOS", "touch y" + String.valueOf(y));
Canvas c = holder.lockCanvas();
//c.drawColor(Color.BLACK);
Node n = new Node(bitmap, c, x, y);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
collision = false;
//nodes.add(n);
if (!nodes.isEmpty()){
for (Node no : nodes) {
collision = no.isHere(x, y);
if (collision){
break;
}
}
}
if(!collision){
nodes.add(n);
}
c.drawColor(Color.BLACK);
if (!nodes.isEmpty()){
for (Node no : nodes) {
no.Draw();
c.drawLine(x, y, event.getX(), event.getY(), paint);
Log.d("Node POS","Node X,Y: " + String.valueOf(no.xPosition) + " " + String.valueOf(no.yPosition));
}
}
holder.unlockCanvasAndPost(c);
break;
}
return true;
}
});
}
In the class given below is used to handle and draw node
package com.example.mindmapping;
import android.graphics.Bitmap;
import android.graphics.Canvas;
public class Node {
public Bitmap img;
public Canvas c;
public float xPosition, yPosition, topLeft;
int width, height,gResId;
boolean isItOk;
public Node(Bitmap b,Canvas canv, float xP, float yP) {
img = b;
c = canv;
width = b.getWidth();
height = b.getHeight();
xPosition = xP - (width/2);
yPosition = yP - (height/2);
}
public void SetPos( float xP, float yP) {
xPosition = xP - (width/2);
yPosition = yP - (height/2);
}
public boolean isHere(float x, float y){
x = (float) (x + width * 0.5);
y = (float) (y + height * 0.5);
if((x > xPosition - width * 0.5) && (x < xPosition + width * 0.5) && (y > yPosition - height * 0.5) && (y < yPosition + height * 0.5) ){
return true;
}
return false;
}
//#SuppressWarnings("static-access")
public void Draw() {
c.drawBitmap(img, xPosition, yPosition, null);
}
}
I'm developing in android, and I have to do a Paint for android.
I'm using the code below and, when I execute the code, the draw works, but, it seems that there are 2 surfaces to paint, and when you draw in one, the other one disappears.
I was looking for the exact error, but cannot find it.
Here is the code :
import java.util.Random;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;
public class MainActivity extends Activity {
MySurfaceView mySurfaceView;
Button Cuadrado;
Button Circulo;
Button Color;
Button Linea;
private boolean Bcuadrado,Bcirculo,Bcolor=false;
private boolean Blinea=true;
Canvas canvas = new Canvas();
#TargetApi(11)
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout mainLayout =(RelativeLayout)findViewById(R.id.main_layout_id );
View view =getLayoutInflater().inflate(R.layout.itemlayout, mainLayout,false);
mainLayout.addView(view);
mySurfaceView = new MySurfaceView(this);
Cuadrado=(Button)findViewById(R.id.button1);
Circulo=(Button)findViewById(R.id.button2);
Color=(Button)findViewById(R.id.button3 );
Linea=(Button)findViewById(R.id.button4 );
int w= view.getWidth();
int h= view.getHeight();
float x=view.getX();
float y= view.getY();
mySurfaceView.setY(100);
mainLayout.addView(mySurfaceView);
Cuadrado.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(Bcuadrado==false){
Bcuadrado=true;
Bcirculo=false;
Bcolor=false;
Blinea=false;
}
}
});
Circulo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Bcirculo){
Bcuadrado=false;
Bcirculo=true;
Bcolor=false;
Blinea=false;
}
}
});
Color.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Bcolor){
Bcuadrado=false;
Bcirculo=false;
Bcolor=true;
Blinea=false;
}
}
});
Linea.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Blinea){
Bcuadrado=false;
Bcirculo=false;
Bcolor=false;
Blinea=true;
}
}
});
}
class MySurfaceView extends SurfaceView{
Path path;
SurfaceHolder surfaceHolder;
volatile boolean running = false;
private Paint paint = new Paint();
float x0=0;
float x1=0;
float y0=0;
float y1=0;
Random random = new Random();
public MySurfaceView(Context context) {
super(context);
surfaceHolder = getHolder();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(android.graphics.Color.WHITE);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(Blinea){
if(event.getAction() == MotionEvent.ACTION_DOWN){
path = new Path();
path.moveTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
path.lineTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_UP){
path.lineTo(event.getX(), event.getY());
}
if(path != null){
canvas = surfaceHolder.lockCanvas();
canvas.drawPath(path, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcuadrado){
if(event.getAction()==MotionEvent.ACTION_DOWN){
x0=event.getX();
y0=event.getY();
}
else if(event.getAction()==MotionEvent.ACTION_UP){
x1=event.getX();
y1=event.getY();
canvas = surfaceHolder.lockCanvas();
canvas.drawRect(x0, y0, x1, y1, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcirculo){
if(event.getAction()==MotionEvent.ACTION_DOWN){
x0=event.getX();
y0=event.getY();
}
else if(event.getAction()==MotionEvent.ACTION_UP){
x1=event.getX();
canvas=surfaceHolder.lockCanvas();
canvas.drawCircle(x0, y0,(x1-x0), paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcolor){
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
canvas=surfaceHolder.lockCanvas();
paint.setColor(0xff000000 + (r << 16) + (g << 8) + b);
surfaceHolder.unlockCanvasAndPost(canvas);
}
return true;
}
}
}
it seems that there are 2 surfaces to paint, and when you draw in one, the other one disappears.
That is exactly how SurfaceView works - it's double buffered. You need to redraw whole frame each time.
From Android's doc: SurfaceHolder
The content of the Surface is never preserved between unlockCanvas() and lockCanvas(), for this reason, every pixel within the Surface area must be written. The only exception to this rule is when a dirty rectangle is specified, in which case, non-dirty pixels will be preserved.
The canvas does not save what you previously wrote to it. Every time you call unlock(), you must redraw everything all over again.
i m trying to implement freehand crop in android using canvas. i use drawPath and store it in List and draw it in canvas path drawing ok,
like this
but now i want to make all pixel in that path in side area with this code but i dont no how to do it..
public Bitmap getBitmapWithTransparentBG(Bitmap srcBitmap)
{
Bitmap result = srcBitmap.copy(Bitmap.Config.ARGB_8888, true);
int nWidth = result.getWidth();
int nHeight = result.getHeight();
for (int y = 0; y < nHeight; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
for (int i = 0; i < points.size() ; i++)
{
}
result.setPixel(x, y, Color.TRANSPARENT);
}
}
return result;
}
points is list of path coordinate hear is code for draw path
package com.org;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class SomeView extends View implements OnTouchListener {
private Paint paint;
List<Point> points;
int DIST = 2;
boolean flgPathDraw = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.waterlilies);
public SomeView(Context c ) {
super(c);
setFocusable(true);
setFocusableInTouchMode(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
this.setOnTouchListener(this);
points = new ArrayList<Point>();
}
public SomeView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
this.setOnTouchListener(this);
points = new ArrayList<Point>();
}
public void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, null);
Path path = new Path();
boolean first = true;
for (int i = 0; i < points.size(); i += 2)
{
Point point = points.get(i);
if (first) {
first = false;
path.moveTo(point.x, point.y);
} else if (i < points.size() - 1) {
Point next = points.get(i + 1);
path.quadTo(point.x, point.y, next.x, next.y);
} else {
path.lineTo(point.x, point.y);
}
}
canvas.drawPath(path, paint);
}
public boolean onTouch(View view, MotionEvent event) {
// if(event.getAction() != MotionEvent.ACTION_DOWN)
// return super.onTouchEvent(event);
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
if (flgPathDraw) {
points.add(point);
}
invalidate();
Log.e("Hi ==>", "Size: " + points.size());
return true;
}
public void fillinPartofPath()
{
Point point = new Point();
point.x = points.get(0).x;
point.y = points.get(0).y;
points.add(point);
invalidate();
}
public void resetView()
{
points.clear();
paint.setColor(Color.WHITE);
paint.setStyle(Style.STROKE);
flgPathDraw=true;
invalidate();
}
}
class Point {
public float dy;
public float dx;
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
Hi i think below link for your exact solution, what u try?
Android: Free Croping of Image
Don't forget to put your vote and feedback here.
Lets look at a bit more complex example:
The red point is the point you want to test. You have to find the edges that cross the y coordinate of the red point. In this example 4 edges cross the y coordinate (the blue points).
Now test how much intersections you get on the left side and on the right side of the point you want to check. If there is an odd number of intersections on both sides the point is inside the shape.
update: you can find a more detailed description of this algorithm here
You can use Canvas.clipPath to draw only cropped region. But be awared that this method doesn't work with hardware acceleration so you have to turn it off and use software rendering.
Why does this code only draw a circle once? I cannot for the life of me figure it out. Do I need to do some kind of refresh or something? I am able to get a red dot, to draw once, but any click after does not show a new dot, or even move the previous one.
package ball.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
public class BallActivity extends Activity {
/** Called when the activity is first created. */
BallView bv;
int i = 0;
TextView tv;
//float x = 20;
//float y = 20;
float r = 20;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.top);
LinearLayout main = (LinearLayout) findViewById(R.id.main_view);
//main.addView(new BallView(this, 20, 20, 20));
main.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
i++;
float x = event.getX();
float y = event.getY();
tv.setText("Clicks: " + i + "X: " + x + "Y: " + y);
LinearLayout ll = (LinearLayout) v;
ll.addView(new BallView(ll.getContext(), x, y, 25));
return false;
}
});
}
}
package ball.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.view.View;
public class BallView extends View{
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
float x;// = 20;
float y;// = 20;
float r;// = 20;
public BallView(Context context, float x, float y, float r) {
super(context);
this.x = x;
this.y = y;
this.r = r;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.RED);
//paint.setStyle(Style.FILL_AND_STROKE);
//canvas.drawColor(Color.WHITE);
canvas.drawCircle(x, y, r, paint);
}
}
Change your LinearLayout to an AbsoluteLayout. I think what's happening is that your first BallView is actually taking up the entirety of the LinearLayout view group and any other views you add to it are being pushed out of the layout.
Also, look into using addView(View, AbsoluteLayout.LayoutParams) instead, so you can set the size/position of the ball there as opposed to in BallView.onDraw, which will allow smaller regions of your layout to be marked dirty.