Android edittext gets cut off - java

I created a custom EditText view in onDraw that is meant to have a red margin line. The problem is that when you scroll down, the line disappears. This code simply draws a margin whos width is pre-defined in the values folder and then colors it with a pre-defined color from colors.xml. Here's my code:
package com.lioncode.notepad;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.EditText;
Public class LinedEditText extends EditText {
private static Paint linePaint;
static {
linePaint = new Paint();
linePaint.setColor(Color.DKGRAY);
linePaint.setStyle(Style.STROKE);
}
public LinedEditText(Context context, AttributeSet attributes) {
super(context, attributes);
init();
}
private Paint marginPaint;
private float margin;
private int paperColor;
private void init() {
Resources myResources = getResources();
marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
marginPaint.setColor(myResources.getColor(R.color.notepad_margin));
paperColor = myResources.getColor(R.color.notepad_paper);
margin = myResources.getDimension(R.dimen.notepaper_margin);
}
#Override
protected void onDraw(Canvas canvas) {
Rect bounds = new Rect();
int firstLineY = getLineBounds(0, bounds);
int lineHeight = getLineHeight();
int totalLines = Math.max(getLineCount(), getHeight() / lineHeight);
for (int i = 0; i < totalLines; i++) {
int lineY = firstLineY + i * lineHeight;
canvas.drawLine(bounds.left, lineY, bounds.right, lineY, linePaint);
}
// draw margin
canvas.drawLine(margin, 0, margin, getMeasuredHeight(), marginPaint);
// move the text from along the margin
canvas.save();
canvas.translate(margin, 0);
super.onDraw(canvas);
}
}

Replace total lines with a high number the user will probably never reach.

Related

Draw a circle in Android Canvas when previous circle was selected at predefined positions

This is my first time using Canvas in Android.
I am creating an app that would display circles at certain positions on the screen one at a time (positions are selected randomly). New circle should be drawn after the previous one was selected/touched, and the previous one should disappear.
I have some ideas about it: to keep an arraylist of Point objects(each object contains x,y coordinate of the centre of the circle) and randomly select one each time the circle is drawn on the screen. So first I am populating an array of points. I also know how to randomly select the element from arraylist.
My biggest confustion is how to connect onDraw and onTouchEvent methods with each other? I know I should check if the circle was selected and only then draw a new circle at the randomly selected position, but I m not sure how to make a call for onDraw() method from the onTouchEvent...
Could you please help with this issue?
My code is below:
package com.example.researcher.heatmap;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* TODO: document your custom view class.
*/
public class MyView extends View {
Paint paint;
ArrayList<Point> points = new ArrayList<>();
public MyView(Context context) {
super(context);
init();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
// Load attributes
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
populateArrayList();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setStyle(Paint.Style.STROKE);
canvas.drawColor(Color.WHITE);
int i=1; // should be random, will randomize later
for(Point p: points) {
p.x = points.get(i).x;
p.y = points.get(i).y;
canvas.drawCircle(p.x, p.y, 50, paint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int i=1;
for(Point p: points) {
Canvas canvas = new Canvas();
p.x = points.get(i).x;
p.y = points.get(i).y;
canvas.drawCircle(p.x, p.y, 50, paint);
}
postInvalidate();
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
break;
}
}
postInvalidate();
return true;
}
public void populateArrayList(){
points.clear();
points.add(new Point(120, 120));
points.add(new Point(150, 320));
points.add(new Point(280, 200));
}
}
Thank you Chris for your help! I really appreciate it.
Here is my solution if someone will need it for reference
package com.example.researcher.heatmap;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* TODO: document your custom view class.
*/
public class MyView extends View {
Paint paint;
ArrayList<Point> points = new ArrayList<>();
private int pointsPos = 0; //Which point we will be drawing
public float x;
public float y;
public int radius = 150;
public MyView(Context context) {
super(context);
x = this.getX();
y = this.getY();
init();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
x = this.getX();
y = this.getY();
init();
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
x = this.getX();
y = this.getY();
init();
}
private void init() {
// Load attributes
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
populateArrayList();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setStyle(Paint.Style.STROKE);
canvas.drawColor(Color.WHITE);
canvas.drawCircle(points.get(pointsPos).x, points.get(pointsPos).y, radius, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
//Check if the point press is within the circle
if(contains(event, points.get(pointsPos))){
Random r = new Random(System.nanoTime());
pointsPos = r.nextInt(points.size());; //between 0 and points.length
postInvalidate();
}
case MotionEvent.ACTION_CANCEL: {
break;
}
}
postInvalidate();
return true;
}
private boolean contains(MotionEvent event, Point point) {
float xTouch = event.getX();
float yTouch = event.getY();
if ((xTouch - point.x) * (xTouch - point.x) + (yTouch - point.y) * (yTouch - point.y) <= radius * radius) {
return true;
}
else {
return false;
}
}
public void populateArrayList(){
points.clear();
points.add(new Point(220, 1020));
points.add(new Point(550, 320));
points.add(new Point(780, 500));
}
}
Class var
private int state = 0 //0 normal, 1 new circle
private int pointPos = 0; //Which point we will be drawing
onDraw was overwriting the x/y of all your other points
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setStyle(Paint.Style.STROKE);
canvas.drawColor(Color.WHITE);
if(state == 1){
pointPos = random(); //between 0 and points.length
state = 0;
}
canvas.drawCircle(points.get(pointsPos).x, points.get(pointsPos).y, 50, paint);
}
onTouchEvent: Drawing should only be done on the ondraw, use flags/states to keep track of what you should be doing on the next draw call
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//Though these days this is usually done on the up event
//Check if the point press is within the circle
if(contains(event, points.get(pointPos))){
state = 1;
postInvalidate();
}
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
break;
}
}
postInvalidate();
return true;
}

Touch event not working in custom extend view

I have Activity.java and PaintView extends View implements OnTouchListener interface. In this program I have to click on buttons (pink and blue background button) and select a shape and drag into the view area.
I need help I have been trying last few days.
MainActivity.java
package com.easyway2win;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button butnPink,butnBlue;
public PaintView paintView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
butnPink = (Button)findViewById(R.id.pinkColor);
butnBlue = (Button)findViewById(R.id.blueColor);
View paintView = (View)findViewById(R.id.view1);
}
public void clickMe(View view){
int intColor = 0;
String hexColor = null;
switch(view.getId()){
case R.id.pinkColor:
intColor = getResources().getColor(R.color.pink);
hexColor = String.format("#%06X", (0xFFFFFF & intColor));
Log.d("Hi", "I am pink color code " + hexColor);
break;
case R.id.blueColor:
intColor = getResources().getColor(R.color.blue);
}
PaintView paintView = new PaintView(this);
paintView.setPaintColour(intColor);
}// end [ clickMe method ]
}
package com.easyway2win;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
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;
import android.widget.Toast;
PaintView.java
public class PaintView extends View implements OnTouchListener{
private Paint paint;
private Path path;
private Bitmap buffer = null;
private Canvas penCanvas = null;
int colour = 0;
public PaintView(Context context) {
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5f);
// create the Paint and set its color
paint = new Paint();*/
path = new Path();
}
public PaintView(Context context, AttributeSet attrs ){
super(context, attrs);
}
public PaintView(Context context, AttributeSet attrs, int defStyle/*Context context, Rect rectangle, Paint paint*/) {
super(context,attrs,defStyle);
// this.rectangle = rectangle;
// this.paint = paint;
}
public void setPaintColour(int colour){
paint.setColor(colour);
//Log.d("Hi", "I am in setPaintColour Method" );
}
#Override
protected void onDraw(Canvas canvas) {
/* canvas.drawRect(rectangle,paint);*/
canvas.drawPath(path, paint);
}
#Override
public boolean onTouch(View v, MotionEvent evt) {
int action = evt.getAction() & MotionEvent.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:{
//Toast.makeText(getContext(), "Action Down", Toast.LENGTH_LONG);
//Log.d("Down", "Pointer Down");
break;
}
case MotionEvent.ACTION_POINTER_DOWN : {
Log.d("CV", "Other point down");
break;
}
case MotionEvent.ACTION_POINTER_UP : {
Log.d("CV", "Other point up");
break;
}
case MotionEvent.ACTION_UP : {
Log.d("CV", "Pointer up");
break;
}
}
return true;
}
}
The null pointer exception happens when you try to call methods on the paint object before it has been created. The paint = new Paint(); line needs to be moved earlier in the PaintView constructor, or paint can simply be initialized where it is declared.
public class PaintView extends View implements OnTouchListener{
private Paint paint;
// alternate: private Paint paint = new Paint();
private Path path;
private Bitmap buffer = null;
private Canvas penCanvas = null;
int colour = 0;
public PaintView(Context context) {
super(context);
// create the Paint and set its color
paint = new Paint();*/
// alternate: skip this line and use the alternate above
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5f);
path = new Path();
}
It also looks like the PaintView is never added into your layout. The object is created, but it isn't attached to anything in the UI. If you have a reference to the ViewGroup (LinearLayout, etc.), a new View can be added to it with the addView method. If another View needs to be removed from the layout, use removeView.

text renders over solid rect, but doesnt render over gradient

I'm new to Android development, and trying to render a button to a Canvas object in an onDraw method, basically text over a backfield. It's a good way to get my feet wet with some of the rendering commands.
I am able to fill a solid rectangle and then draw centered text over it, but when I try to fill a gradient rectangle, and then draw text over it, the text doesn't draw.
Code is below, cobbled together from various examples. Basically:
DO_PAINT=0, DO_GRADIENT=0 -> text renders
DO_PAINT=1, DO_GRADIENT=0 -> solid rectangle with text on top
DO_PAINT=0, DO_GRADIENT=1 -> gradient rectangle (no text) !!!
So something about my gradient drawing interferes with my text rendering. I'm guessing that I'm leaving something in a bad state in the Paint object, but I'm not sure what property that would be...
Any insight or thoughts are greatly appreciated...
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.view.View;
import android.graphics.Paint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Canvas;
import android.util.Log;
import android.view.MotionEvent;
import android.app.Activity;
public class cMyView extends View
{
public cMyView(Context context, Activity owner_activity)
{
super(context);
}
final Paint m_paint = new Paint();
public String m_Text = "Button";
private final Rect textBounds = new Rect();
public Typeface m_TypeFace = Typeface.create("Arial",Typeface.NORMAL);
public int m_TextColor = Color.argb(255,0,0,0);
public int m_TextSize = 32;
#Override
protected void onDraw(Canvas canvas) {
Rect m_Bounds = new Rect(100,100,500,200);
boolean DO_PAINT = false;
boolean DO_GRADIENT = true;
if ( DO_PAINT) {
m_paint.setStyle(Paint.Style.FILL);
m_paint.setColor(Color.GREEN);
canvas.drawRect(m_Bounds, m_paint);
}
if (DO_GRADIENT) {
m_paint.setShader(new LinearGradient(0, m_Bounds.top, 0, m_Bounds.bottom, Color.BLACK, Color.WHITE, Shader.TileMode.MIRROR));
canvas.drawRect(m_Bounds.left, m_Bounds.top, m_Bounds.right, m_Bounds.bottom, m_paint);
}
m_paint.setColor(m_TextColor);
m_paint.setTextSize(m_TextSize);
m_paint.setTypeface(m_TypeFace);
m_paint.getTextBounds(m_Text, 0, m_Text.length(), textBounds);
double x = m_Bounds.left + m_Bounds.width()/2 - textBounds.exactCenterX();
double y = m_Bounds.top + m_Bounds.height()/2 - textBounds.exactCenterY();
canvas.drawText(m_Text, (float) x, (float) y, m_paint);
}
}
Just add an another Paint for text, this is worked for me, and I found the reason, if you comment 2-nd row in DO_GRADIENT case (in your code), then will see that text is gradient, it mean that it draw, but have same gradient as background have, and becomes invisible.
public class CustomView extends View {
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
final Paint m_paint = new Paint();
public String m_Text = "Button";
private final Rect textBounds = new Rect();
public Typeface m_TypeFace = Typeface.create("Arial",Typeface.NORMAL);
public int m_TextColor = Color.argb(255, 0, 0, 0);
public int m_TextSize = 32;
private final Paint textPaint = new Paint();
#Override
protected void onDraw(Canvas canvas) {
Rect m_Bounds = new Rect(100,100,500,200);
boolean DO_PAINT = true;
boolean DO_GRADIENT = true;
if ( DO_PAINT) {
m_paint.setStyle(Paint.Style.FILL);
m_paint.setColor(Color.GREEN);
canvas.drawRect(m_Bounds, m_paint);
}
if (DO_GRADIENT) {
m_paint.setShader(new LinearGradient(0, m_Bounds.top, 0, m_Bounds.bottom, Color.BLACK, Color.WHITE, Shader.TileMode.MIRROR));
canvas.drawRect(m_Bounds.left, m_Bounds.top, m_Bounds.right, m_Bounds.bottom, m_paint);
}
m_paint.setColor(m_TextColor);
m_paint.setTextSize(m_TextSize);
m_paint.setTypeface(m_TypeFace);
m_paint.getTextBounds(m_Text, 0, m_Text.length(), textBounds);
double x = m_Bounds.left + m_Bounds.width()/2 - textBounds.exactCenterX();
double y = m_Bounds.top + m_Bounds.height()/2 - textBounds.exactCenterY();
textPaint.setColor(m_TextColor);
textPaint.setTextSize(m_TextSize);
textPaint.setTypeface(m_TypeFace);
canvas.drawText(m_Text, (float) x, (float) y, textPaint);
}

How can I animate the single part of paint in the ondraw canvas?

I am making a custom view application. And I want to animate the single part of paint(Tap to start)in the onDraw canvas, Here is my code, I adjusted the source code from the internet and put it in my application.
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.Align;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
public class CustomView extends ImageView{
private static Paint paint;
private int w;
private int h;
private Animation scaleAnim;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
//To customize the brown border
paint = new Paint();
paint.setStrokeWidth(20);
paint.setColor(Color.rgb(123, 92, 13));
paint.setStyle(Paint.Style.STROKE);
}
//To fit with the situation of vertical and horizontal orientation
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
this.w = w;
this.h = h;
super.onSizeChanged(w, h, oldw, oldh);
}
private void createAnim(Canvas canvas) {
scaleAnim = new ScaleAnimation(0f,1f,0f,1f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scaleAnim.setRepeatMode(Animation.REVERSE);
scaleAnim.setRepeatCount(Animation.INFINITE);
scaleAnim.setDuration(10000L);
scaleAnim.setInterpolator(new AccelerateDecelerateInterpolator());
startAnimation(scaleAnim);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// creates the animation the first time
if (scaleAnim == null) {
createAnim(canvas);
}
//To obtain the height and width
int height = this.getMeasuredHeight();
int width = this.getMeasuredWidth();
//To draw the dark green background
canvas.drawColor(Color.rgb(15, 37, 7));
//To paint the brown border
canvas.drawRect(10, 10, width - 10, height - 10, paint);
//To obtain the image
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.main_icon);
//To place the image on the right bottom corner
canvas.drawBitmap(bmp, canvas.getWidth()-bmp.getWidth(), canvas.getHeight()-bmp.getHeight() , paint);
//To obtain the custom font and make it available to use
Typeface typeface = Typeface.createFromAsset(getContext().getAssets(),
"fonts/KG.ttf");
//To create a new paint style for text
Paint textStyle = new Paint();
//Set the font style
textStyle.setTypeface(typeface);
//To set text color to white
textStyle.setColor(Color.rgb(255, 255, 255));
//To set text size
textStyle.setTextSize(100);
//To make text centered
textStyle.setTextAlign(Align.CENTER);
//To print the text as main title with style specified
canvas.drawText("L E A R N E R !", w/2, h/2, textStyle);
//To create a new paint and customize them
Paint jpStyle = new Paint();
jpStyle.setColor(Color.rgb(252,71,71));
jpStyle.setTextSize(50);
jpStyle.setTextAlign(Align.CENTER);
jpStyle.setTypeface(typeface);
canvas.drawText("# J A P A N", w/2, h/2+50, jpStyle);
//To create a new paint and customize them
Paint startStyle = new Paint();
startStyle.setColor(Color.WHITE);
startStyle.setTextSize(40);
startStyle.setTextAlign(Align.CENTER);
startStyle.setTypeface(typeface);
canvas.drawText("> Tap to Start <", w/2, h/2+170, startStyle);
}
}

Faster way of displaying offscreen bitmap using android/java

I have started to learn android and java using the android studio beta. As a first simple test app I am trying to get a basic Mandelbrot renderer working. I have gotten it to display, but now I want it faster. Can anyone give advice on the following?
The docs say canvas.drawbitmap is depreciated. What should I use instead? What is the fastest ways to show a bitmap onscreen?
How can I show the progress of the calculations? If I unremark the 2 lines marked "update display after each line has been calculated" there is no updating during the calculations and the extra calls to canvas.drawbitmap really slow it all down (79 seconds compared to 31 seconds without it).
Is there anything I can do to speed up the general math calls?
I have tried to keep it as simple as possible for this example.
Many thanks for any tips for a newbie. I don't want to learn bad habits from the start if possible.
The layout has a single imageview aligned to the screen. The full code is
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import java.text.DecimalFormat;
import java.util.Random;
import static android.graphics.Color.argb;
import static android.graphics.Color.rgb;
public class myActivity extends Activity {
myView myview;
Bitmap bmp;
Canvas myCanvas;
ImageView img;
Paint paint;
Boolean started=false;
Integer ih,iw,i,redraws,fw,fh;
long startms,finishms;
Random rnd;
double xmin,xmax,ymin,ymax,padding,bailout,bailout_squared,stepx,stepy,x,y,magnitude;
double realiters,tweenval;
Integer col,colval1,colval2;
Integer iterations,maxiterations,superx,supery,samplepixels,square_samplepixels,xloop,yloop;
double zr,zi,cr,ci,xloopdouble,yloopdouble;
int[] colorpalette = new int[256];
int[] pixels;
int r,g,b,r1,g1,b1,r2,g2,b2,totalr,totalg,totalb;
private void init(){
//screen size
Display display = getWindowManager().getDefaultDisplay();
Point sizePoint = new Point();
paint = new Paint();
display.getSize(sizePoint);
iw=sizePoint.x;
ih=sizePoint.y;
//pixels array
fw=iw;
fh=ih;
pixels=new int[fw*fh];
//create bitmap
bmp=Bitmap.createBitmap(iw, ih, Bitmap.Config.RGB_565);
//create canvas
myCanvas =new Canvas();
myCanvas.setBitmap(bmp);
img = (ImageView) findViewById(R.id.imageView1);
rnd = new Random();
}
// calculates and displays the Mandelbrot fractal
private void Mandelbrot(){
startms= SystemClock.uptimeMillis();
//coordinates
// xmin=-1.6345100402832;
// xmax=-1.63043992784288;
// ymin=-0.00209962230258512;
// ymax=0.00209259351094558;
xmin=-2.3;
xmax=2.3;
ymin=-2.1;
ymax=2.1;
fw=iw;
fh=ih;
//adjust coords to match screen aspect
if (iw<ih) {
padding=(xmax-xmin)/iw*(ih-iw);
ymin=ymin-padding/2.0;
ymax=ymax+padding/2.0;
} else {
padding=(ymax-ymin)/ih*(iw-ih);
xmin=xmin-padding/2.0;
xmax=xmax+padding/2.0;
}
bailout=8.0; //needs to be higher than default 2 for the CPM coloring to be smooth
bailout_squared=bailout*bailout;
maxiterations=64;
samplepixels=1;
square_samplepixels=samplepixels*samplepixels;
//random color palette
for (col=0;col<256;col++){
colorpalette[col]=android.graphics.Color.argb(255,rnd.nextInt(256),rnd.nextInt(256),rnd.nextInt(256));
}
stepx=(xmax-xmin)/fw/samplepixels;
stepy=(ymax-ymin)/fh/samplepixels;
for (yloop=0;yloop<fh;yloop++){
for (xloop=0;xloop<fw;xloop++){
totalr=0;
totalg=0;
totalb=0;
r=0;
g=0;
b=0;
xloopdouble=(double)xloop;
yloopdouble=(double)yloop;
for (supery=0;supery<samplepixels;supery++)
{
for (superx=0;superx<samplepixels;superx++)
{
cr = xmin+xloopdouble/(double)fw*(xmax-xmin)+(stepx*(double)superx);
ci = ymin+yloopdouble/(double)fh*(ymax-ymin)+(stepy*(double)supery);
zr = 0.0;
zi = 0.0;
magnitude=0.0;
for(iterations=0; iterations<maxiterations; iterations++)
{
i=iterations;
x = (zr * zr - zi * zi) + cr;
y = (zi * zr + zr * zi) + ci;
magnitude=(x * x + y * y);
if(magnitude>bailout_squared) break;
zr = x;
zi = y;
}
if (iterations>=maxiterations) {
r=0;
g=0;
b=0;
} else {
//CPM smooth colors
realiters=iterations+1-((Math.log(Math.log(Math.sqrt(magnitude)))/Math.log(2.0)));
colval1=(int) Math.floor(realiters % 255);
colval2=(colval1+1) % 255;
tweenval=realiters-Math.floor(realiters);
r1=Color.red(colorpalette[colval1]);
g1=Color.green(colorpalette[colval1]);
b1=Color.blue(colorpalette[colval1]);
r2=Color.red(colorpalette[colval2]);
g2=Color.green(colorpalette[colval2]);
b2=Color.blue(colorpalette[colval2]);
r=(int) (r1+((r2-r1)*tweenval));
g=(int) (g1+((g2-g1)*tweenval));
b=(int) (b1+((b2-b1)*tweenval));
}
totalr=totalr+r;
totalg=totalg+g;
totalb=totalb+b;
}
}
r=(int) totalr/square_samplepixels;
g=(int) totalg/square_samplepixels;
b=(int) totalb/square_samplepixels;
//update pixels array
pixels[xloop+yloop*fw]=rgb(r, g, b);
}
//update display after each line has been calculated
//myCanvas.drawBitmap(pixels,0,fw,0,0,fw,fh,false,null);
//if (img != null) img.invalidate();
}
myCanvas.drawBitmap(pixels,0,fw,0,0,fw,fh,false,null);
finishms=SystemClock.uptimeMillis();
}
private void updateTimeTaken(){
//turn antialiasing on
paint.setAntiAlias(true);
// draw some text using FILL style
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(30);
DecimalFormat myFormatter = new DecimalFormat("#,###,###");
paint.setColor(Color.BLACK);
myCanvas.drawText("Time taken = " + myFormatter.format(finishms - startms) + " ms", 15, 45, paint);
paint.setColor(Color.WHITE);
myCanvas.drawText("Time taken = " + myFormatter.format(finishms - startms) + " ms", 14, 44, paint);
paint.setColor(Color.BLACK);
myCanvas.drawText("Screen size = " + String.valueOf(iw) + " x " + String.valueOf(ih), 15, 85, paint);
paint.setColor(Color.WHITE);
myCanvas.drawText("Screen size = " + String.valueOf(iw) + " x " + String.valueOf(ih), 14, 84, paint);
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
//fullscreen no menu
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
redraws=0;
super.onCreate(savedInstanceState);
myview = new myView(this);
setContentView(myview);
init();
started=true;
Mandelbrot();
updateTimeTaken();
}
private class myView extends View{
public myView(Context context){
super(context);
}
#Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//draw off screen bitmap to screen
if (started==true){
canvas.drawBitmap(bmp,0,0,paint);
}
}
}
}

Categories