I have class MyView that extends View class. MyView should draw filled triangle. I drew a triangle but I cannot get it filled. This is my onDraw() method:
@O
This answer provides a bit of clarity on where the numbers given in the answer by @Egis come from. (this will draw an upside down equilateral triangle and is written in kotlin)
class TriangleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
val paint = Paint()
val path = Path()
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas ?: return
canvas.drawPath(configurePath(canvas.width.toFloat(), path), configurePaint(paint))
}
fun getHeight(width: Double): Float {
return Math.sqrt((Math.pow(width, 2.0) - Math.pow((width / 2), 2.0))).toFloat()
}
fun configurePaint(paint: Paint): Paint {
paint.color = android.graphics.Color.WHITE
paint.isAntiAlias = true
return paint
}
fun configurePath(width: Float, path: Path): Path {
path.lineTo((width / 2f), getHeight(width.toDouble()))
path.lineTo(width, 0F)
path.lineTo(0f, 0f)
return path
}
}
The get height function is Pythagoras' Theorem and will always find the height of an equilateral triangle to be ~87% of its side length
Gist can be found here, it contains code for the other direction
these links are very usefull.
I would like to point out that you should never initiialize an object from onDraw() as it gets called multiple times and leads to performance problems.
I recently created a small demo app drawing various shapes, including triangles, rectangles and spirals. Here is the code for drawing the triangles. For full context, reference the project. In this app, the user can draw a triangle as a single drawing or a composition of two triangles forming into one as the user scrolls. The increasing triangle growth is accomplished through the principles of Triangle Similarity, with each smaller triangle similar to the large triangle in the end.
Project: https://github.com/jdgreene2008/android_custom_views
Source Excerpt: https://github.com/jdgreene2008/android_custom_views/blob/master/CustomUiComponents/app/src/main/java/com/jarvis/dragdropresearch/views/FlashShapeView.java
private void drawTriangleShape(Canvas canvas, RectF bounds,
TriangleInterpolator triangleInterpolator, Paint paint) {
paint.setStyle(Paint.Style.FILL);
float baseInterpolation = triangleInterpolator
.getInterpolatedValues()[TriangleInterpolator.INTERPOLATION_VALUES_BASE];
float altitudeInterpolation = triangleInterpolator
.getInterpolatedValues()[TriangleInterpolator.INTERPOLATION_VALUES_ALTITUDE];
// *** Construct the Left Triangle ** //
// Bottom left vertex
float bottomLeftX = bounds.left;
float bottomLeftY = bounds.bottom;
// Bottom right corner
float bottomRightX = bottomLeftX + baseInterpolation;
float bottomRightY = bounds.bottom;
//Top Vertex
float topX = bottomRightX;
float topY = bottomRightY - altitudeInterpolation;
Path leftTriangle = new Path();
leftTriangle.lineTo(bottomLeftX, bottomLeftY);
leftTriangle.lineTo(bottomRightX, bottomRightY);
leftTriangle.lineTo(topX, topY);
leftTriangle.lineTo(bottomLeftX, bottomLeftY);
canvas.drawPath(leftTriangle, paint);
if (triangleInterpolator.isSymmetric()) {
// *** Construct the Right Triangle ** //
bottomLeftX = bounds.right - baseInterpolation;
bottomLeftY = bounds.bottom;
bottomRightX = bounds.right;
bottomRightY = bounds.bottom;
topX = bottomLeftX;
topY = bottomRightY - altitudeInterpolation;
Path rightTriangle = new Path();
rightTriangle.lineTo(bottomLeftX, bottomLeftY);
rightTriangle.lineTo(bottomRightX, bottomRightY);
rightTriangle.lineTo(topX, topY);
rightTriangle.lineTo(bottomLeftX, bottomLeftY);
canvas.drawPath(rightTriangle, paint);
}
}
I've found the answer
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(android.graphics.Color.BLACK);
canvas.drawPaint(paint);
paint.setStrokeWidth(4);
paint.setColor(android.graphics.Color.RED);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setAntiAlias(true);
Point a = new Point(0, 0);
Point b = new Point(0, 100);
Point c = new Point(87, 50);
Path path = new Path();
path.setFillType(FillType.EVEN_ODD);
path.lineTo(b.x, b.y);
path.lineTo(c.x, c.y);
path.lineTo(a.x, a.y);
path.close();
canvas.drawPath(path, paint);
}