Как нарисовать заполненный треугольник на андроиде Canvas
У меня есть класс MyView, который расширяет класс View. MyView должен рисовать заполненный треугольник. Я нарисовал треугольник, но я не могу его заполнить. Это мой метод onDraw():
@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.moveTo(a.x, a.y);
path.lineTo(b.x, b.y);
path.moveTo(b.x, b.y);
path.lineTo(c.x, c.y);
path.moveTo(c.x, c.y);
path.lineTo(a.x, a.y);
path.close();
canvas.drawPath(path, paint);
}
Вот что я получаю в результате:
![enter image description here]()
Ответы
Ответ 1
Я нашел ответ
@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);
}
Ответ 2
Этот ответ дает немного ясности в отношении того, откуда берутся числа, указанные в ответе от @Egis. (это нарисует перевернутый равносторонний треугольник и записывается в котлин)
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
}
}
Функция get height Теорема Пифагора и всегда будет находить, что высота равностороннего треугольника составляет ~ 87% от его длины стороны
Gist можно найти здесь, он содержит код для другого направления
Ответ 3
эти ссылки очень полезны.
Ответ 4
Я хотел бы указать, что вы никогда не должны инициализировать объект из onDraw(), поскольку он вызывается несколько раз и приводит к проблемам с производительностью.
Ответ 5
Недавно я создал небольшое демонстрационное приложение для рисования различных форм, в том числе треangularьников, прямоangularьников и спиралей. Вот код для рисования треangularьников. Для полного контекста, обратитесь к проекту. В этом приложении пользователь может нарисовать треangularьник в виде одного рисунка или композицию из двух треangularьников, образующих один во время прокрутки пользователем. Увеличивающийся рост треangularьника достигается по принципу сходства треangularьников, где каждый меньший треangularьник похож на большой треangularьник в конце.
Проект: https://github.com/jdgreene2008/android_custom_views
Выдержка из источника: 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);
}
}