I am learning Android and trying to draw different shapes on the Canvas. At the moment I am stuck with an oval with different angles:
I've tried to use path.addRoundRect() method (the one which takes array of radiuses), but couldn't figure out what values should I pass there in order to achieve such shape. I've also tried using path.lineTo(), but could not achieve such result (it was kind of similar, but still not what I needed). What would be a good solution to accomplish this?
Edit 1 :What I have tried is following:
Path path= new Path();
path.moveTo(x - radius, y - radius/ 1.5f);
path.lineTo(x - radius/ 4, y - radius);
path.lineTo(x, y - radius);
path.lineTo(x + radius/ 2, y - radius);
path.lineTo(x + radius, y - radius/ 2);
path.lineTo(x, y + radius/ 2);
path.lineTo(x - radius/ 2, y + radius/ 1.5f);
path.lineTo(x - radius, y + radius/ 4);
path.lineTo(x - radius, y - radius/ 1.5f);
path.close();
Paint pathPaint = new Paint();
pathPaint.setColor(Color.BLACK);
pathPaint.setStrokeWidth(2.5f);
pathPaint.setDither(true);
pathPaint.setStyle(Style.STROKE);
pathPaint.setStrokeJoin(Join.ROUND);
pathPaint.setStrokeCap(Cap.ROUND);
pathPaint.setPathEffect(new CornerPathEffect(20));
pathPaint.setAntiAlias(true);
canvas.drawOval(new RectF(x - radius, y - radius+ 2, x + radius-2, y + radius- 2), pathPaint);
canvas.drawPath(path, pathPaint);
X and Y are some coordinates on a display and radius is a radius of the circle (I started drawing with a circle). Its equal to 14 px.
I've also tried this way:
float[] radii = new float[] {
5,
5,
1,
1,
5,
1,
1,
1,
};
path.addRoundRect(new RectF(x - radius, y - radius, x + radius,
y + radius),
radii, Direction.CW);
canvas.drawPath(path, pathPaint);
Try the Canvas.skew() function. There is a good example at the URL below. Skew "tilts" the points being drawn. You'll get different results based on the current center of the canvas, so translate() as needed to get the results you want.
http://css3files.com/transform/
Related
I want to make resizable triangle like facility provide into paint or other software, may simple triangle draw and also move using coordinate but how I can resize this triangle I don’t know can anybody help me for this task.
i want like this
Making of the triangle into canvas is so easy here using this function may draw triangle into canvas
public void drawTriangle(Canvas canvas, Paint paint, int x, int y, int width) {
int halfWidth = width / 2;
Path path = new Path();
path.moveTo(x, y - halfWidth);
path.lineTo(x - halfWidth, y + halfWidth);
path.lineTo(x + halfWidth, y + halfWidth);
path.lineTo(x, y - halfWidth);
path.close();
canvas.drawPath(path, paint);
}
I want to draw text below circle in canvas. Following is my code but text is drawn above circle.
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
canvas.drawText(text, 0, (radius*2), textPaint);
Looking at it properly you need to set the y value based on height of the canvas, same way you did the circle, then adjust it to be Below based on radius.
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
canvas.drawText(text, 0, (getHeight() / 2) + radius, textPaint);
One thing that may be confusing you is that the origion is the top left. And that increase in Y is downwards
You may need to add a few extra pixels based on text height. so (getHeight() / 2) + radius + 20
i am drawing canavasarc but some how it always start from left i am it should start from middle
float x = 0.25f;
final float radius = x * (new Float(dpi));
mRadius = Math.round(radius) + 20;
mRect = new RectF(
getWidth() + mStrokeWidth, getWidth() + mStrokeWidth, getWidth() + (mRadius / 2) - mStrokeWidth, getWidth() + (mRadius / 2) - mStrokeWidth
);
canvas.drawArc(mRect, lastDegree, mSectionDegree, false, mPaint);
why this view always starts from left even i have given gravity centre still
float Degree = 270 + (mGap / 2);
for (int i = 0; i < mTotalSections; i++) {
fillColor(i);
canvas.drawArc(mRect, Degree, mDegree, false, mPaint);
Degree += mDegree + mGap;
Paint mPaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint1.setStrokeWidth(1);
mPaint1.setStyle(Paint.Style.FILL);
mPaint1.setAntiAlias(true);
mPaint1.setTextSize(15 * getResources().getDisplayMetrics().density);
mPaint1.setColor(getResources().getColor(black));
mPaint1.setTextAlign(Paint.Align.CENTER);
canvas.drawText(text, mRect.centerX(), mRect.centerY(), mPaint1);
}
I'm not sure about what you want to do but your rect looks weird. A rect more like that should would be better:
mRect = new RectF(
0 + mStrokeWidth, 0 + mStrokeWidth, getWidth() - mStrokeWidth, getHeight - mStrokeWidth
);
But a little draw about what you want and the values of your angle would be perfect ;). I will edit my answer if you provide it.
Edit:
So if you want a circle in the middle of your custom view you can do something like that:
RectF mRect = new RectF(
50 + mStrokeWidth, 50 + mStrokeWidth, getWidth() -50 - mStrokeWidth, getHeight() -50 - mStrokeWidth
);
canvas.drawArc(mRect, 0,360,false,paint);
result(the blue lines are the limit of my view):
You have to modify the 50 to fit what you want ;).
If you want an arc that stick to the edges with an angle of 180 degrees:
RectF mRect = new RectF(
mStrokeWidth, mStrokeWidth, getWidth() - mStrokeWidth, getHeight() - mStrokeWidth
);
canvas.drawArc(mRect, 0,180,false,paint);
Result:
Let me know if you need something else.
consider two circles with (0,0) as center and 110 and 210 as radius respectively...
i.e i have CENTER as (0,0) and CIRCLE 1 radius as 110 and CIRCLE 2 radius as 210.
Now i need to move an object tball in between these two circles.
Here is my code--
public void run() {
while (isitok == true) {
// perform drawing
if (!holder.getSurface().isValid()) {
continue;
}
Canvas canvas = holder.lockCanvas();
canvas.drawARGB(255, 150, 150, 10);
// System.out.println("Canvas matrix -" + canvas.getm));
Paint p = new Paint();
// canvas.drawBitmap(tball, (x - tball.getWidth()) / 2,
// (y - tball.getHeight()) / 2, p);
p.setStyle(Paint.Style.STROKE);
p.setColor(Color.WHITE);
p.setColor(Color.parseColor("#0101DF"));
canvas.drawCircle(canvas.getWidth() / 2,
canvas.getHeight() / 2, 60, p);
canvas.drawCircle(canvas.getWidth() / 2,
canvas.getHeight() / 2, 110, p);
float x = (canvas.getWidth() / 2) - (tball.getWidth() / 2);
float y = (canvas.getHeight() / 2) - 110 + (110 - 60) / 2
- (tball.getHeight() / 2);
canvas.drawBitmap(tball, x, y, p);
float movingpts[];
holder.unlockCanvasAndPost(canvas);
}
}
Circle coordinates are
X = MX + R * cos( angle )
Y = MY + R * sin( angle )
where (MX,MY) is the center or midpoint of the circle and R the radius. For screen coordinates it is sometimes better to use
Y = MY - R * sin( angle )
to get the angle consistent with mathematical conventions on circle orientation.
I'm learning Android and now I'm experimenting with the Canvas class.
I would like to draw a regular (equilateral) triangle inscribed into a known circle.
I think there must be a easier way to do it than getting into trigonomery, pythagoras,...
Doing the trig is the most straightforward method that I've found. Below is a function for drawing an equilateral triangle in the normal, "pointing upward" orientation. I've posted a more sophisticated implementation here that also handles rotating the triangle.
private void drawCircumscribedTriangle(Canvas canvas, float circleCenterX, float circleCenterY, float radius, Paint paint) {
float xOffsetFromCenter = FloatMath.cos((float)Math.PI/6) * radius;
float yOffsetFromCenter = FloatMath.sin((float)Math.PI/6) * radius;
canvas.drawLine(circleCenterX, circleCenterY - radius, circleCenterX + xOffsetFromCenter, circleCenterY + yOffsetFromCenter, paint);
canvas.drawLine(circleCenterX + xOffsetFromCenter, circleCenterY + yOffsetFromCenter, circleCenterX - xOffsetFromCenter, circleCenterY + yOffsetFromCenter, paint);
canvas.drawLine(circleCenterX - xOffsetFromCenter, circleCenterY + yOffsetFromCenter, circleCenterX, circleCenterY - radius, paint);
}
Thanks to Acj, I got it, But it wasn't exactly what I wanted, because I wanted it to be filled (It's my fault because I didn't specify it).
Anyway, I adapted Acj's code to my needs, and here it is:
private void drawCircumscribedTriangle(Canvas canvas, float circleCenterX, float circleCenterY, float radius, Paint paint) {
float xOffsetFromCenter = FloatMath.cos((float)Math.PI/6) * radius;
float yOffsetFromCenter = FloatMath.sin((float)Math.PI/6) * radius;
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(circleCenterX, circleCenterY - radius);
path.lineTo(circleCenterX + xOffsetFromCenter, circleCenterY + yOffsetFromCenter);
path.lineTo(circleCenterX - xOffsetFromCenter, circleCenterY + yOffsetFromCenter);
path.lineTo(circleCenterX, circleCenterY - radius);
path.lineTo(circleCenterX, circleCenterY - radius);
canvas.drawPath(path, paint);
}
Once more, all the merit is for Acj
As FloatMath.cos(float) is deprecated since API 23, this answer to a tricky equilateral question needs the following lines of its code updating to
float xOffsetFromCenter = ((float)Math.PI/6) * radius;
float yOffsetFromCenter = ((float)Math.PI/6) * radius;