How to draw filled triangle on android Canvas

前端 未结 5 531
鱼传尺愫
鱼传尺愫 2020-12-09 09:12

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         


        
相关标签:
5条回答
  • 2020-12-09 09:53

    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

    0 讨论(0)
  • 2020-12-09 09:54

    these links are very usefull.

    1. https://github.com/swapgo20/Android-Hand-Drawing
    2. https://github.com/codepath/android_guides/wiki/Basic-Painting-with-Views
    3. https://github.com/Korilakkuma/CanvasView
    0 讨论(0)
  • 2020-12-09 09:57

    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.

    0 讨论(0)
  • 2020-12-09 10:04

    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);
            }
        }
    
    0 讨论(0)
  • 2020-12-09 10:07

    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);
    }
    
    0 讨论(0)
提交回复
热议问题