Calculos para desenhar formas

Prezados, estou desenvolvendo um trabalho para uma cadeira de computação gráfica onde inserindo os parametros de centro e raio, a aplicação deve realizar o cálculo dos pontos para desenhar um circulo. O que entendi até agora é desenhar um ponto no plano cartesiano e outro espelho, mas minhas dúvidas principais são:
Como setar um único pixel com base no resultado do cálculo? eu vi um comando setpixel, mas não entendi como usá-lo. Após desenhar um ponto é só incrementar para desenhar os demais? Se alguém for fera em desenho de primitivas gráficas agradeceria muito se me ajudasse, pois estou quebrando a cabeça com esse exercício

Segue abaixo o código que estou tentando desenvolver

public class Circulo {
	
	public void circulo ( float xcentro,ycentro, raio){
		float x,y,r2;
		r2=raio*raio;
		calculos para desenho
		(xcenter,ycenter,+raio)//vai desenhar o primeiro ponto;
		(xcenter,ycenter,-raio)//vai desenhar o ponto espelho;
	
	}
	
}

Você quer desenhar “manualmente”, ponto por ponto, sem funções que já fazem isso como a drawOval, né?

Será necessário funções para achar seno e cosseno. Experimente o código a seguir; sugiro modificá-lo com vários valores diferentes para entender bem o que tá acontecendo ali.

import javax.swing.*;
import java.awt.*;

class App extends JFrame {
    private static int POINT_SIZE = 3;

    @Override public void paint(Graphics g) {
        super.paint(g);
        drawCircle(g, 200, 200, 100, 100, Color.RED);
    }

    public void drawCircle(Graphics g, int posicaoX, int posicaoY,
                           int raio, int quantidadeDePontos, Color cor) {

        double distanciaEntrePontos = 2 * Math.PI / quantidadeDePontos;

        for (int i = 0; i < quantidadeDePontos; i++) {
            double cos = Math.cos(i * distanciaEntrePontos);
            double sin = Math.sin(i * distanciaEntrePontos);

            int x = (int) ( cos * raio + posicaoX );
            int y = (int) ( sin * raio + posicaoY );

            g.setColor(cor);
            g.fillRect(x, y, POINT_SIZE, POINT_SIZE);
        }
    }

    public static void main(String... args) {
        JFrame frame = new App();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Aqui um print do código acima:

Obs.: Não há métodos para desenhar pontos no Swing, então usei o fillRect para desenhar retângulos minúsculos pra enganar ^^!

Obrigada ; )

1 curtida

Pessoal é possível usar o BufferedImage para efetuar os desenhos, colorindo os pixes calculados? Alguém já usou para esse fim?

The class java.awt.BufferedImage has a method setRGB(int x, int y, int rgb) which sets the color of an individual pixel. Additionally, you might want to look at java.awt.Color, especially its getRGB() method, which can convert Colors into integers that you can put into the int rgb parameter of setRGB.

Olá, @lyah.

Minha resposta anterior fez algum sentido? Era mais ou menos o que vc tava procurando? Achei interessante o lance com desenhos de circulos e gostaria de saber se entendi bem o seu problema.

Enfim. BufferedImage, né? Dá sim pra usar e eu precisei fazer apenas pequenas modificações no código que mostrei anteriormente.

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

class App extends JFrame {
    private static int WINDOW_WIDTH  = 400;
    private static int WINDOW_HEIGHT = 400;

    @Override public void paint(Graphics g) {
        super.paint(g);

        BufferedImage imagem = new BufferedImage( WINDOW_WIDTH, WINDOW_HEIGHT, BufferedImage.TYPE_INT_RGB );

        drawCircleInImage(imagem, 200, 200, 100, 120, Color.WHITE);

        g.drawImage(imagem, 0, 0, null);
    }

    public void drawCircleInImage(BufferedImage imagem, int posicaoCentroX, int posicaoCentroY,
                           int raio, int quantidadeDePontos, Color cor) {

        double distanciaEntrePontos = 2 * Math.PI / quantidadeDePontos;

        for (int i = 0; i < quantidadeDePontos; i++) {
            double cos = Math.cos(i * distanciaEntrePontos);
            double sin = Math.sin(i * distanciaEntrePontos);

            int x = (int) ( cos * raio + posicaoCentroX );
            int y = (int) ( sin * raio + posicaoCentroY );

            imagem.setRGB(x, y, cor.getRGB());
        }
    }

    public static void main(String... args) {
        JFrame frame = new App();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Se comparar o método drawCircle (da outra resposta) com o drawCircleInImage verá que as diferenças foram minímas.

Por isso eu comentei sobre modificar valores e testar pra entender bem como funciona, pois quando entendemos como o código funciona, fica fácil fazer modificações para que se adeque as nossas necessidades.

O princípio é mesmo. setRGB desenha 1 pixel que é, essencialmente, o que eu quis simular com o fillRect do outro código.

Segue um print do resultado do código acima.

1 curtida

Por que você precisa criar seu próprio método para desenhar círculos? você vai ter que se preocupar com anti-alias também?

Oi !

Sim, sua resposta faz muito sentido para mim, porém estou desenvolvendo este trabalho para a faculdade, na cadeira de computação gráfica, e fico com medo de usar qualquer método gráfico, por isso quero usar o bufferedImage…
Mas tu sabe que eu estava sofrendo em relação aos cálculos, pois o professor não quer que use apenas um circulo, e sim um circulo desenhado através de cálculo de octantes "escreva em C#, Java, C ou C++ um programa que receba o centro e o raio de um círculo e calcule os pontos o algoritmo de simetria de octantes."
Então acho que usar as funções seno e cosseno vai dar certo pois vai calcular os pontos dos quadrantes que desenha o círculo…
Se você tem interesse no desenho de circulo, de uma olhada nesse conteúdo que ele passou para nos auxiliar
http://groups.csail.mit.edu/graphics/classes/6.837/F98/Lecture6/circle.html
Tks, vou implementar seu algorítimo e testar, obrigada mesmo! :smile:

Porque é um trabalho de computação gráfica, onde o circulo deve ser desenhado na mão…

O que é anti-alias?

Ah, legal.

Vi o link; muito legal. Nos exemplos, a única dúvida é com relação aquele raster, que deve mesmo ser uma BufferedImage.

Nossa, Computação Gráfica? É em Ciência da Computação? Será que vão aprender OpenGL ou DirectX?

Boa sorte no trabalho.

Sim, ciência da computação… Nós estamos usando o Processing…
Você faz ciência também?

Obrigada, eu senti um pouco de dificuldade (muita), mas agora está mais claro…

Boa Páscoa!

Não faço Ciência da Computação, mas comecei este ano no Análise e Desenvolvimento de Sistemas. Gosto muito de CC, mas ainda não dá pra fazer.

O negócio de desenhar circulos aprendi pois queria fazer um joguinho que precisa de alguma coisa relacionada com isso. É bastante divertido este tipo de coisa.

Vlw, boa Páscoa!

É uma técnica para remover serrilhamento na imagem renderizada.

http://www.pcmanias.com/os-tipos-de-anti-aliasing-existentes-e-a-sua-diferenca-fxaa-smaa-msaa-e-outros/

Que maravilha de postagem!!! Eu estava doido atras desse calculo de desenhar circulo manualmente para fazer incremento de X e Y em um loop afim de fazer um objeto ficar se movendo em circulo… e funcionou =)))))) E aqui um video onde eu uso esse efeto em um tipo de tiro