سؤال

لقد حاولت استخدام طريقة السجل مع ارتفاع متساوي وعرض ولكن كما يزيد القطر من الدائرة يصبح الأسوأ يبحث. ماذا يمكنني أن أفعل للحصول على دائرة مظهرية لائقة بغض النظر عن الحجم. كيف يمكنني تنفيذ مكافحة التعرج في جافا أو طريقة أخرى.

هل كانت مفيدة؟

المحلول

كما اتضح، Java2D (الذي أفترض هو ما تستخدمه) هو بالفعل جيدة جدا في هذا! هناك برنامج تعليمي لائق هنا: http://www.javaworld.com/javaworld/jw-08-1998/JW-08-Media.html.

الخط المهم هو:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);

نصائح أخرى

يمكنك ضبط تلميحات التقديم:

Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);

شيئين قد يساعدان:

  1. يستخدم Graphics2D.draw(Shape) مع مثيل java.awt.geom.Ellipse2D بدلا من Graphics.drawOval
  2. إذا كانت النتيجة لا تزال غير مرضية، فحاول استخدام Graphics2D.setRenderingHint لتمكين التحف

مثال

public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    Shape theCircle = new Ellipse2D.Double(centerX - radius, centerY - radius, 2.0 * radius, 2.0 * radius);
    g2d.draw(theCircle);
}

انظر إجابة جوزيف للحصول على مثال على setRenderingHint

بالطبع، قمت بتعيين دائرة نصف قطرها إلى ما تحتاجه:

@Override
public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    Ellipse2D.Double hole = new Ellipse2D.Double();
    hole.width = 28;
    hole.height = 28;
    hole.x = 14;
    hole.y = 14;
    g2d.draw(hole);
}

بفضل Oleg Estekhin للإشارة إلى تقرير الأخطاء، لأنه يشرح كيفية القيام بذلك.

إليك بعض الدوائر الصغيرة قبل وبعدها. تضخيم عدة مرات لرؤية شبكة بكسل.

Circles before and after

النزول إلى صف، إنهم يتحركون قليلا حسب كميات فرعية.

العمود الأول هو دون تقديم تلميحات. والثاني هو مع انتياس فقط. والثالث هو مع antialias والوضع النقي.

لاحظ كيف يتم تلميحات ANTIALAIS فقط، الدوائر الثلاثة الأولى هي نفسها، وآخران هو نفسه أيضا. يبدو أن هناك بعض الانتقال المنفصل يحدث. ربما تقريب في مرحلة ما.

إليك الرمز. إنه في جيثون للحصول على قابلية القراءة، لكنه يدفع مكتبة وقت تشغيل Java أسفله ويمكن نقله دون خسارة إلى مصدر Java المكافئ، مع نفس التأثير بالضبط.

from java.lang import *
from java.io import *
from java.awt import *
from java.awt.geom import *
from java.awt.image import *
from javax.imageio import *

bim = BufferedImage(30, 42, BufferedImage.TYPE_INT_ARGB)
g = bim.createGraphics()
g.fillRect(0, 0, 100, 100)
g.setColor(Color.BLACK)
for i in range(5):
    g.draw(Ellipse2D.Double(2+0.2*i, 2+8.2*i, 5, 5))

g.setRenderingHint( RenderingHints.  KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON)

for i in range(5):
    g.draw(Ellipse2D.Double(12+0.2*i, 2+8.2*i, 5, 5))

g.setRenderingHint( RenderingHints.  KEY_STROKE_CONTROL,
                    RenderingHints.VALUE_STROKE_PURE)

for i in range(5):
    g.draw(Ellipse2D.Double(22+0.2*i, 2+8.2*i, 5, 5))

#You'll probably want this too later on:
#g.setRenderingHint( RenderingHints.  KEY_INTERPOLATION,
#                    RenderingHints.VALUE_INTERPOLATION_BICUBIC)
#g.setRenderingHint( RenderingHints.  KEY_RENDERING, 
#                    RenderingHints.VALUE_RENDER_QUALITY)

ImageIO.write(bim, "PNG", File("test.png"))

ملخص: تحتاج إلى حد سواء VALUE_ANTIALIAS_ON و VALUE_STROKE_PURE للحصول على دوائر المظهر المناسبة مع دقة فرعية.

عدم القدرة على رسم "دائرة مظهرية" مرتبطة بالصوت القديم 6431487.

لا يساعد تحويل الفتحة على التحف على الكثير - فقط تحقق من نوع "الدائرة" التي ينتجها السجل () أو drawshape (كسوف) عندما يكون حجم الدائرة المطلوبة 16 بكسل (لا يزال شائعا جدا على أيقونة الحجم) والحصافة قيد التشغيل. ستبدو أكبر الدوائر القاسية بشكل أفضل لكنها لا تزال غير متماثلة، إذا كان شخص ما يهتم بالنظر إليهم عن كثب.

يبدو أنه لرسم "دائرة مظهرية لائقة" يتعين على المرء رسم واحد يدويا. دون الحافضة، ستكون خوارزمية دائرة الوسط (هذه سؤال لديه إجابة مع رمز جافا جميلة لذلك).

التحرير: 06 سبتمبر 2017

هذه خوارزمية اخترعت من قبل لرسم دائرة على مصفوفة عدد صحيح. يمكن استخدام الفكرة نفسها لكتابة دائرة داخل BufferedImage. إذا كنت تحاول رسم تلك الدائرة باستخدام رسومات الفصل، فلا تبحث عن الإجابة عليك (إلا إذا كنت ترغب في تعديل كل لون ملون مع g.drawline (x، y، x + 1، y)، ولكن يمكن ذلك أن تكون بطيئة جدا).

protected boolean runOnCircumference(int[][] matrix, int x, int y, int ray, int color) {
    boolean ret;
    int[] rowUpper = null, rowInferior = null, rowCenterUpper = null, rowCenterInferior = null;

    if (ret = ray > 0) {
        if (ray == 1) {
            matrix[y][x + 1] = color;
            rowUpper = matrix[++y];
            rowUpper[x] = color;
            rowUpper[x + 2] = color;
            matrix[y][x] = color;
        } else {
            double rRay = ray + 0.5;
            int r = 0, c = 0, ray2 = ray << 1, ray_1 = ray - 1, halfRay = (ray >> 1) + ray % 2, rInf,
                    ray1 = ray + 1, horizontalSymmetricOldC;
            // draw cardinal points

            rowUpper = matrix[ray + y];
            rowUpper[x] = color;
            rowUpper[x + ray2] = color;
            matrix[y][x + ray] = color;
            matrix[ray2 + y][x + ray] = color;

            horizontalSymmetricOldC = ray1;
            rInf = ray2;
            c = ray_1;
            for (r = 0; r < halfRay; r++, rInf--) {

                rowUpper = matrix[r + y];
                rowInferior = matrix[rInf + y];

                while (c > 0 && (Math.hypot(ray - c, (ray - r)) < rRay)) {

                    rowUpper[x + c] = color;
                    rowUpper[x + horizontalSymmetricOldC] = color;
                    rowInferior[x + c] = color;
                    rowInferior[x + horizontalSymmetricOldC] = color;

                    // get the row pointer to optimize
                    rowCenterUpper = matrix[c + y];
                    rowCenterInferior = matrix[horizontalSymmetricOldC + y];
                    // draw
                    rowCenterUpper[x + r] = color;
                    rowCenterUpper[x + rInf] = color;
                    rowCenterInferior[x + r] = color;
                    rowCenterInferior[x + rInf] = color;
                    horizontalSymmetricOldC++;
                    c--;
                }
            } // end r circle
        }
    }
    return ret;
}

حاولت ذلك عدة مرات، والتحقق من صحة تكنولوجيا المعلومات يدويا، لذلك أعتقد أنها ستعمل. لم أحصل على أي تحقق من النطاق فقط لتبسيط التعليمات البرمجية. آمل أن يساعدك الجميع ويرغبون في رسم دائرة على مصفوفة (على سبيل المثال، هؤلاء المبرمون الذين يحاولون إنشاء ألعاب الفيديو الخاصة بهم على الرمز النقي وتحتاج إلى إدارة خريطة لعبة موجهة نحو المصفوفة لتخزين الكائنات الكذب على الكائنات خريطة اللعبة [إذا كنت بحاجة إلى مساعدة في هذا، أرسل لي رسالة عبر البريد الإلكتروني]).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top