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);
}
Related
I'm looking at making something that looks like the following:
Which is basically a rectangle shape on the top left thats been rotated, and then two underneath it, tiled like it is.
I've had a go at doing it but just can't get it done, basically I use:
int x = getWidth();
int y = getHeight();
canvas.save();
canvas.rotate(-45);
canvas.drawRect(x/2, y/2, x/2+100, y/2+40, paint);
canvas.restore();
And I've noticed that what should be a rectangle rotated near the centre of the screen is instead one that is to the top right of the screen. When I try doing something similar to (0,0, 100,100) I don't get any rectangle at all.
I guess I'm confused whether the coordinate system changes when the rotation of the canvas is done, and what would be the easiest way in looking into getting the image above on android (besides just creating it in photoshop and adding the png).
The single argument rotate(angle) will use 0,0 as the pivot point.
If you want to rotate about your object, you should calculate some point on it to rotate about and use the 3 argument rotate(angle, pivotX, pivotY), ie:
int x = getWidth();
int y = getHeight();
canvas.save();
canvas.rotate(-45, x / 2, y / 2);
canvas.drawRect(x / 2, y / 2, x / 2 + 100, y / 2 + 40, paint);
canvas.restore();
I made your design just for fun:
int x = getWidth();
canvas.rotate(-45);
canvas.drawRect(-x, 0, x, h, green);
canvas.drawRect(-x, h, 0, 2 * h, purple);
canvas.drawRect(0, h, x, 2 * h, blue);
Where h is the height of the rectangle.
Can someone explain exactly how rotation of the canvas about a point works ?
I have lines and I want to draw text parallel to each line. I have worked out the trigonometry required to calculate the angle of the line and it`s centre point.
When I try rotate the canvas about the start point of the line, then draw the text and restore, I am always getting strange offsets which obviously means I do not quiet get how the rotation is working ...
Can someone explain what happens when you rotate the canvas about a point and how the then drawing on co-ords X,Y translates back ?
see the following class:
class V extends View {
private Paint mPaint;
public V(Context context) {
super(context);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(0xffeeeeee);
mPaint.setTextSize(24);
}
#Override
protected void onDraw(Canvas canvas) {
float x = 100;
float y = 50;
float dx = 60;
float dy = 40;
canvas.drawLine(x, y, x + dx, y + dy, mPaint);
canvas.save();
float degrees = (float) (180 * Math.atan2(dy, dx) / Math.PI);
canvas.rotate(degrees, x, y);
canvas.drawText("text", x, y, mPaint);
canvas.restore();
}
}
now i hope everything should be clear how canvas rotation works...
In hardware accelerated custom View added in ScrollView or ListView both of the following code snippets produces same result: (please ignore best practises for a sec)
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// centering stuff
float centerX = getWidth() / 2f;
float centerY = getHeight() / 2f;
float size = 80;
float halfSize = size / 2f;
float left = centerX - halfSize;
float top = centerY - halfSize;
RectF oval = new RectF(left, top, left + size, top + size);
Path path = new Path();
path.addArc(oval, 160, 359);
Paint paint = new Paint();
paint.setTextSize(30);
paint.setStyle(Style.STROKE);
canvas.drawTextOnPath("Hello world", path, 0, 0, paint); //<--- line A
canvas.drawCircle(centerX, centerY, 10, paint); //<--- line B
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// centering stuff
float centerX = getWidth() / 2f;
float centerY = getHeight() / 2f;
float size = 80;
float halfSize = size / 2f;
float left = centerX - halfSize;
float top = centerY - halfSize;
RectF oval = new RectF(left, top, left + size, top + size);
Path path = new Path();
path.addArc(oval, 160, 359);
Paint paint = new Paint();
paint.setTextSize(30);
paint.setStyle(Style.STROKE);
canvas.drawCircle(centerX, centerY, 10, paint); //<--- line B
canvas.drawTextOnPath("Hello world", path, 0, 0, paint); //<--- line A
}
Same Result:
But with later code snippet, as soon as you scroll the ScrollView (I have invisible dummy View below so I can scroll) and helloworld touches ActionBar, something very intersting happens and you see something that intelligent humankind used to see in old Windows OS .
I know drawTextOnPath() is not supported in hardware accelration mode, but then why it works if you call it first?
drawTextOnPath() is supported by hardware acceleration after Android 4.1
This is mentioned officially here: https://code.google.com/p/android/issues/detail?id=37925
but the next comment seems to indicate your problem in a way so maybe a bug.
Of course for pre 4.1 just dont make it use HW accel - Set a software layer type on your View by calling View.setLayerType(View.LAYER_TYPE_SOFTWARE, null) and try to get a tradeoff on perf vs errors
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/
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;