2010-12-28 19 views
2

私はアンドロイドで矩形を描きたかったのですが、左、上、右、下を指定するだけではありません。私が持っているのは4つの頂点座標です。 、アンドロイドの斜め矩形を描く

image of an oblique rectangle

私は回転のいくつかの種類を実行したり、canvas.rotate()を使用するために行列を使用することができるかどうかを確認しようとしてきた:矩形は水平方向が、斜めではないので、下の長方形の画像のようなもの私はまだそれを行う方法が明確ではない。誰かがこのような長方形を描く方法を教えてくれますか?

答えて

2

私はこの問題に他人のソリューションを見ることに興味があると思いますが、もっと簡単な方法が存在しない場合は、ここで私はそれを苦労して実装方法は次のとおりです。

public void drawLineThick(GL10 gl, int thickness, FloatBuffer whichBuffer) 
{ 
    gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); 
    final float x0 = whichBuffer.get(0); 
    final float x1 = whichBuffer.get(2); 
    final float y0 = whichBuffer.get(1); 
    final float y1 = whichBuffer.get(3); 

    boolean slopeZeroCase = false; 
    boolean undefinedSlopeCase = false; 
    boolean slopeOneCase = false; 
    boolean slopeNegOneCase = false; 
    boolean slopeSmall = false; 
    boolean slopeBig = false; 
    float boxThickness = thickness * .001f; 

    //Slope (y2-y1)/(x2-x1) 
    float m = 0.0f; 

    //b parameter of y=mx+b formula, b=y-mx 
    float b = 0.0f; 

    //Special cases for handling when the slope is zero, undefined 
    //both (line of length zero), one, or negative one. 
    if (y1 - y0 == 0) 
    { 
     slopeZeroCase = true; 
    } 

    if (x1 - x0 == 0) 
    { 
     undefinedSlopeCase = true; 
    } 

    //If the slope isn't going to be zero or undefined, it's safe to 
    //actually try to calculate it so that we don't have a "divide by zero" 
    //by accident 
    if (slopeZeroCase == false && undefinedSlopeCase == false) 
    { 
     m = ((y1 - y0)/(x1 - x0)); 
     b = (y0 - (m*x0)); 
    } 

    if (m == 1.0f) 
    { 
     slopeOneCase = true; 
    } 

    if (m == -1.0f) 
    { 
     slopeNegOneCase = true; 
    } 

    if ((m > 0 && m < 1) || (m < 0 && m > -1)) 
    { 
     slopeSmall = true; 
    } 
    else 
    { 
     slopeBig = true; 
    } 

    //float tempFloat[] = new float[8]; 

    //Normal line where there is a slope involved 
    if (slopeZeroCase == false && undefinedSlopeCase == false && slopeOneCase == false && slopeNegOneCase == false && slopeSmall == true) 
    { 

     /** 
     *   Given a sloped line, in order to make it, "thicker", 
     *   one must offset the original line by + and - the 
     *   thickness, in essence creating a box. The formula 
     *   for the points of a given box below (in the direction drawn) 
     *   will be: 
     * 
     *   p0   p1 
     *   *----------* 
     *   |   | 
     *   |   | 
     *   |   | 
     *   |   | 
     *   *----------* 
     *   p3   p2 
     *   
     */   

     //p1, x 
     tempFloat[0] = x0; 

     //p1, y 
     tempFloat[1] = y0 + boxThickness; 

     //p2, x 
     tempFloat[2] = x1; 

     //p2, y 
     tempFloat[3] = y1 + boxThickness; 

     //p3, x 
     tempFloat[4] = x1; 

     //p3, y 
     tempFloat[5] = y1 - boxThickness; 

     //p4, x 
     tempFloat[6] = x0; 

     //p4, y 
     tempFloat[7] = y0 - boxThickness; 
    } 

    else if (slopeZeroCase == false && undefinedSlopeCase == false && slopeOneCase == false && slopeNegOneCase == false && slopeSmall == false) 
    { 

     /** 
     *   Given a sloped line, in order to make it, "thicker", 
     *   one must offset the original line by + and - the 
     *   thickness, in essence creating a box. The formula 
     *   for the points of a given box below (in the direction drawn) 
     *   will be: 
     * 
     * 
     * 
     *   p0   p1 
     *   *----------* 
     *   |   | 
     *   |   | 
     *   |   | 
     *   |   | 
     *   *----------* 
     *   p3   p2 
     *   
     */   

     //p1, x 
     tempFloat[0] = x0 + boxThickness; 

     //p1, y 
     tempFloat[1] = y0; 

     //p2, x 
     tempFloat[2] = x1 + boxThickness; 

     //p2, y 
     tempFloat[3] = y1; 

     //p3, x 
     tempFloat[4] = x1 - boxThickness; 

     //p3, y 
     tempFloat[5] = y1; 

     //p4, x 
     tempFloat[6] = x0 - boxThickness; 

     //p4, y 
     tempFloat[7] = y0; 
    } 


    //Horizontal line case, only need to change the y to be +- thickness 
    else if (slopeZeroCase == true && undefinedSlopeCase == false && slopeOneCase == false && slopeNegOneCase == false) 
    { 
     //Log.i("draw", "Horizontal"); 
     //p1, x 
     tempFloat[0] = x0; 

     //p1, y 
     tempFloat[1] = y0 + boxThickness; 

     //p2, x 
     tempFloat[2] = x1; 

     //p2, y 
     tempFloat[3] = y1 + boxThickness; 

     //p3, x 
     tempFloat[4] = x1; 

     //p3, y 
     tempFloat[5] = y1 - boxThickness; 

     //p4, x 
     tempFloat[6] = x0; 

     //p4, y 
     tempFloat[7] = y0 - boxThickness; 
    } 

    //Vertical line case, only need to change the x to be +- thickness 
    else if (slopeZeroCase == false && undefinedSlopeCase == true && slopeOneCase == false && slopeNegOneCase == false) 
    { 
     //Log.i("draw", "Vertical"); 
     //p1, x 
     tempFloat[0] = x0 + boxThickness; 

     //p1, y 
     tempFloat[1] = y0; 

     //p2, x 
     tempFloat[2] = x1 + boxThickness; 

     //p2, y 
     tempFloat[3] = y1; 

     //p3, x 
     tempFloat[4] = x1 - boxThickness; 

     //p3, y 
     tempFloat[5] = y1; 

     //p4, x 
     tempFloat[6] = x0 - boxThickness; 

     //p4, y 
     tempFloat[7] = y0; 
    } 

    //Case where slope = 1 
    else if (slopeZeroCase == false && undefinedSlopeCase == false && slopeOneCase == true && slopeNegOneCase == false) 
    { 
     //Log.i("draw", "OneSlope"); 
     //p1, x 
     tempFloat[0] = y0 - boxThickness; 

     //p1, y 
     tempFloat[1] = x0 + boxThickness; 

     //p2, x 
     tempFloat[2] = y1 - boxThickness; 

     //p2, y 
     tempFloat[3] = x1 + boxThickness; 

     //p3, x 
     tempFloat[4] = y1 + boxThickness; 

     //p3, y 
     tempFloat[5] = x1 - boxThickness; 

     //p4, x 
     tempFloat[6] = y0 + boxThickness; 

     //p4, y 
     tempFloat[7] = x0 - boxThickness; 

    } 

    //Case where slope = -1 
    else if (slopeZeroCase == false && undefinedSlopeCase == false && slopeOneCase == false && slopeNegOneCase == true) 
    { 
     Log.i("draw", "OneSlope"); 
     //p1, x 
     tempFloat[0] = -y0 + boxThickness; 

     //p1, y 
     tempFloat[1] = -x0 + boxThickness; 

     //p2, x 
     tempFloat[2] = -y1 + boxThickness; 

     //p2, y 
     tempFloat[3] = -x1 + boxThickness; 

     //p3, x 
     tempFloat[4] = -y1 - boxThickness; 

     //p3, y 
     tempFloat[5] = -x1 - boxThickness; 

     //p4, x 
     tempFloat[6] = -y0 - boxThickness; 

     //p4, y 
     tempFloat[7] = -x0 - boxThickness; 

    } 

    //Allocate the wrapped buffers that OpenGL ES uses for drawing, buffers changed to 
    //be allocated at class scope so that they're not re-allocated every time this 
    //algorithm is run 
    //ByteBuffer tempBoxByteBuffer = ByteBuffer.allocateDirect(tempFloat.length * 4); 
    //tempBoxByteBuffer.order(ByteOrder.nativeOrder()); 
    //FloatBuffer boxFloatBuffer = tempBoxByteBuffer.asFloatBuffer(); 
    boxFloatBuffer.put(tempFloat); 
    boxFloatBuffer.position(0); 

    //Draw triangles using points p0, p1, and p2 for the first, and 
    //p0, p3, and p2 for the second, filling in between. See box 
    //above for diagram of points. Indices also changed to be allocated at class scope 
    //short indices[] = {0, 1, 2, 0, 3, 2}; 
    //ByteBuffer tempIndiceBuffer = ByteBuffer.allocateDirect(indices.length * 2); 
    //tempIndiceBuffer.order(ByteOrder.nativeOrder()); 
    //ShortBuffer indiceBuffer = tempIndiceBuffer.asShortBuffer(); 
    //indiceBuffer.put(indices); 
    //indiceBuffer.position(0); 

    gl.glVertexPointer(2, GL10.GL_FLOAT, 0, boxFloatBuffer); 
    //gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 2); 

    gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indiceBuffer); 

} 

この特定の実装がそのように行われていましたデフォルトのOpenGL ES機能ではない埋め込みボックスを使用することができます。私がしたことは、代わりに2つの三角形を描くことでした。数学にはいくつかの特別なケースが含まれています。ゼロ勾配、1つの勾配、未定義勾配、0より大きいが1より小さいか0より小さいが負の1より大きい、または勾配が1より大きい負の1つの場合。あなたがしなければならないことは、ポイントの各セットの間に三角形の代わりに線のループを描くことです。あなたは塗りつぶされていないボックスを持っています。

+0

私はしばらくのうちにこのコードを見ていませんでしたが、いくつか改善が見られました。それは動作しますが、コードスペースを節約するために排除できるケースがあります。 – moscro

+0

回答があれば、回答の左側にある矢印を確認して回答を受け付けます。 – Javanator

0

回避方法:描画矩形の代わりに を使用して、線を描画しますが、塗りの線幅を設定します。