Cálculo da Equação da Reta para encontrar as coordenadas de um raio

7 respostas
Reginildo

Olá pessoal, estou tentando encontrar uma solução para o problema a seguir:
Eu trabalho com topografia e queria automatizar a solução de um problema. Eu queria criar um programa que fizesse: ao ter uma rua curva (um arco) eu ofereça apenas três pontos a, b, c (suas coordenadas) eu encontre o raio r dessa curva por meio da equação da reta.
Para conseguir isso eu preciso gerar quatro novos pontos p1, p2, p3, p4 onde a partir daí eu possa calcular as coordenadas do raio. Como segue abaixo, eu já criei um código que calcula o raio por meio desses quatro pontos. Porem eu queria criar uma maneira de fazer com que esses quatro pontos fossem criados automaticamente quando eu desse a, b, c e depois conseguisse obter o raio r.

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

import javax.swing.JPanel;
import javax.swing.JTextField;

class Gui {

	private JFrame frame;
	private JTextField textFieldCX1, textFieldCY1, textFieldCX2, textFieldCY2,
			textFieldCX3, textFieldCY3, textFieldCX4, textFieldCY4, coordXRaio,
			coordYRaio;
	private double coordX1, coordY1, coordX2, coordY2, coordX3, coordY3,
			coordX4, coordY4;
	private JButton buttonGeraCoord, buttonLimpar;
	private EncR rVG;
	private JPanel raioPanel;
	private JPanel panelPrimeiroPonto, panelSegundoPonto, panelTerceiroPonto,
			panelQuartoPonto, panelGeraCoordRaio;
	private JPanel imagePanel;
	private ImageIcon imagem;
	private JLabel labelImage, decricaoRaio;
	private Font f, f2;
	private JLabel xp1, yp1, xp2, yp2, xp3, yp3, xp4, yp4, rx, ry;

	public static void main(String[] args) {
		Gui showRun = new Gui();
		showRun.go();
	}

	private void go() {

		frame = new JFrame("TopoInfo");
		frame.setResizable(false);

		frame.setSize(460, 620);
		frame.setLocation(600, 100);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLayout(new BorderLayout());

		panelPrimeiroPonto = new JPanel();
		panelSegundoPonto = new JPanel();
		panelTerceiroPonto = new JPanel();
		panelQuartoPonto = new JPanel();
		panelGeraCoordRaio = new JPanel();

		raioPanel = new JPanel();

		decricaoRaio = new JLabel("Encontre o raio com 4 coordenadas:");
		decricaoRaio.setFont(new Font("Sans Serif", Font.BOLD, 18));

		f = new Font("Sans Serif", Font.ITALIC, 16);
		f2 = new Font("Sans Serif", Font.BOLD, 14);

		textFieldCX1 = new JTextField();
		textFieldCX1.setColumns(9);
		textFieldCX1.setFont(f);

		textFieldCY1 = new JTextField();
		textFieldCY1.setColumns(9);
		textFieldCY1.setFont(f);

		textFieldCX2 = new JTextField();
		textFieldCX2.setColumns(9);
		textFieldCX2.setFont(f);

		textFieldCY2 = new JTextField();
		textFieldCY2.setColumns(9);
		textFieldCY2.setFont(f);

		textFieldCX3 = new JTextField();
		textFieldCX3.setColumns(9);
		textFieldCX3.setFont(f);

		textFieldCY3 = new JTextField();
		textFieldCY3.setColumns(9);
		textFieldCY3.setFont(f);

		textFieldCX4 = new JTextField();
		textFieldCX4.setColumns(9);
		textFieldCX4.setFont(f);

		textFieldCY4 = new JTextField();
		textFieldCY4.setColumns(9);
		textFieldCY4.setFont(f);

		coordXRaio = new JTextField("coordenada X");
		coordXRaio.setColumns(12);
		coordXRaio.setFont(f);
		coordXRaio.setEditable(false);

		coordYRaio = new JTextField("coordenada Y");
		coordYRaio.setColumns(12);
		coordYRaio.setFont(f);
		coordYRaio.setEditable(false);

		xp1 = new JLabel("p1 X:");
		xp1.setFont(f2);
		yp1 = new JLabel("Y:");
		yp1.setFont(f2);
		xp2 = new JLabel("p2 X:");
		xp2.setFont(f2);
		yp2 = new JLabel("Y:");
		yp2.setFont(f2);
		xp3 = new JLabel("p3 X:");
		xp3.setFont(f2);
		yp3 = new JLabel("Y:");
		yp3.setFont(f2);
		xp4 = new JLabel("p4 X:");
		xp4.setFont(f2);
		yp4 = new JLabel("Y:");
		yp4.setFont(f2);
		rx = new JLabel("Raio r X:");
		rx.setFont(f2);
		ry = new JLabel("Y:");
		ry.setFont(f2);

		imagem = new ImageIcon("Figura2.jpg");
		labelImage = new JLabel(imagem, JLabel.LEFT);

		buttonGeraCoord = new JButton("Gerar Coordenada do Raio");

		buttonGeraCoord.addActionListener(new MyGeraRaioListener());

		buttonLimpar = new JButton("Limpar tudo");
		buttonLimpar.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {

				textFieldCX1.setText("");
				textFieldCY1.setText("");
				textFieldCX2.setText("");
				textFieldCY2.setText("");
				textFieldCX3.setText("");
				textFieldCY3.setText("");
				textFieldCX4.setText("");
				textFieldCY4.setText("");
			}
		});

		imagePanel = new JPanel();
		imagePanel.add(labelImage);

		panelPrimeiroPonto.add(xp1);
		panelPrimeiroPonto.add(textFieldCX1);
		panelPrimeiroPonto.add(yp1);
		panelPrimeiroPonto.add(textFieldCY1);

		panelSegundoPonto.add(xp2);
		panelSegundoPonto.add(textFieldCX2);
		panelSegundoPonto.add(yp2);
		panelSegundoPonto.add(textFieldCY2);

		panelTerceiroPonto.add(xp3);
		panelTerceiroPonto.add(textFieldCX3);
		panelTerceiroPonto.add(yp3);
		panelTerceiroPonto.add(textFieldCY3);

		panelQuartoPonto.add(xp4);
		panelQuartoPonto.add(textFieldCX4);
		panelQuartoPonto.add(yp4);
		panelQuartoPonto.add(textFieldCY4);

		raioPanel.add(decricaoRaio);
		raioPanel.add(imagePanel);
		raioPanel.add(panelPrimeiroPonto);
		raioPanel.add(panelSegundoPonto);
		raioPanel.add(panelTerceiroPonto);
		raioPanel.add(panelQuartoPonto);
		raioPanel.add(buttonGeraCoord);
		raioPanel.add(buttonLimpar);

		panelGeraCoordRaio.add(rx);
		panelGeraCoordRaio.add(coordXRaio);
		panelGeraCoordRaio.add(ry);
		panelGeraCoordRaio.add(coordYRaio);

		raioPanel.add(panelGeraCoordRaio);

		frame.getContentPane().add(BorderLayout.NORTH, raioPanel);

		frame.add(raioPanel);
		frame.setVisible(true);
	}

	public class MyGeraRaioListener implements ActionListener {

		public void actionPerformed(ActionEvent arg0) {
			coordX1 = Double.parseDouble(textFieldCX1.getText());
			coordY1 = Double.parseDouble(textFieldCY1.getText());
			coordX2 = Double.parseDouble(textFieldCX2.getText());
			coordY2 = Double.parseDouble(textFieldCY2.getText());
			coordX3 = Double.parseDouble(textFieldCX3.getText());
			coordY3 = Double.parseDouble(textFieldCY3.getText());
			coordX4 = Double.parseDouble(textFieldCX4.getText());
			coordY4 = Double.parseDouble(textFieldCY4.getText());

			rVG = new EncR(coordX1, coordY1, coordX2, coordY2, coordX3,
					coordY3, coordX4, coordY4);
			rVG.count();

			coordXRaio.setText(String.valueOf(rVG.getXR()));
			coordYRaio.setText(String.valueOf(rVG.getYR()));
		}
	}
}

Vai precisar dessa classe:

class EncR {

	private double x1, y1, x2, y2, x3, y3, x4, y4, m1, m2, n1, n2, xR, yR;

	protected EncR(double xP1n, double yP1n, double xP2n,
			double yP2n, double xP3n, double yP3n, double xP4n, double yP4n) {

		x1 = xP1n;
		y1 = yP1n;
		x2 = xP2n;
		y2 = yP2n;
		x3 = xP3n;
		y3 = yP3n;
		x4 = xP4n;
		y4 = yP4n;

	}

	protected void count() {

		m1 = (y2 - y1) / (x2 - x1);
		n1 = -(m1 * x1) + y1;
		m2 = (y4 - y3) / (x4 - x3);
		n2 = -(m2 * x3) + y3;

		xR = -(n1 - n2) / (m1 - m2);
		yR = m1 * xR + n1;
	}

	protected double getXR() {

		return xR;

	}

	protected double getYR() {

		return yR;

	}
}

7 Respostas

E

Suponha que você tenha um arco de círculo (não é um arco de outra curva de segundo grau).

A equação de uma curva de segundo grau é:

ax2 + by2 + cxy + dx + ey + f = 0

Para um círculo, a = b, e c = 0.

Teríamos:

ax2 + ay2 + dx + ey + f = 0

Ou também:

x2 + y2 + Dx + Ey + F = 0

Como você tem 3 pontos (x, y), então você pode resolver um sistema de 3 equações a 3 incógnitas (D, E e F).

O valor do raio é R2 = (D2 + E2 - 4F) / 4

Reginildo

Mas a fómula r² = (d² + e² - 4f)/4 é para conseguir a distancia do raio e não suas coordenadas como é o meu objetivo.
https://www.flickr.com/photos/nildex/[telefone removido]/
A questão aqui é eu conseguir encontrar as coordenadas (x,y) do centro do raio informando apenas as coordenadas(x, y) de A, B, C.

ViniGodoy

Essa curva é descrita por que tipo de equação? Bezier? Splines? Ou você ajusta círculos?

Se for os primeiros casos, você deve definir exatamente o que está chamando de Raio, já que a curva não descreverá necessariamente nem um círculo, nem uma elipse. Se for o terceiro, haverá mais de um raio.

Reginildo

Como calcular as coordenadas do raio no formato “x,y”. O que estou querendo descobrir é: dados 3 pontos coordenados A(x1,y1), B(x2,y2), C(x3,y3), calcule o RAIO(x4,y4) da circunferência.

https://www.flickr.com/photos/nildex/[telefone removido]/

ViniGodoy

Já que talvez você sequer tenha entendido a minha pergunta, pois você só repetiu o que já tinha dito e não explicou a natureza da sua curva, vai aí uma página mais genérica sobre o assunto que contém explicações para alguns casos comuns: http://paulbourke.net/geometry/circlesphere/

Estou partindo do pressuposto que os três pontos são de uma circunferência. Mas esse não é o único tipo de curva que podemos passar sobre 3 pontos. Na verdade, dependendo da posição dos pontos uma circunferência sobre eles pode nem ser possível.

Reginildo

ViniGodoy:
Já que talvez você sequer tenha entendido a minha pergunta, pois você só repetiu o que já tinha dito e não explicou a natureza da sua curva, vai aí uma página mais genérica sobre o assunto que contém explicações para alguns casos comuns: http://paulbourke.net/geometry/circlesphere/

Estou partindo do pressuposto que os três pontos são de uma circunferência. Mas esse não é o único tipo de curva que podemos passar sobre 3 pontos. Na verdade, dependendo da posição dos pontos uma circunferência sobre eles pode nem ser possível.

Desde já agradeço pelo seu link que me parece ser muito útil a primeira olhada e peço desculpas por não ter conseguido explicar o problema com clareza. Não sou muito bom em matemática, mas acho que se enganou quando disse “dependendo da posição dos pontos uma circunferencia sobre eles pode nem ser possível”. Creio que dado 3 pontos uma circunferência sempre é possível, exceto no caso em que os 3 pontos dados estejam em linha reta.
https://www.flickr.com/photos/nildex/[telefone removido]/

ViniGodoy

Sim, estava pensando no caso de 2 ou mais pontos serem colineares, pois inicialmente você falou que estava automatizando um problema de topografia. É possível traçar curvas sobre esses pontos, mas não círculos. É muito comum em agrimensura ou topografia usarmos splines ou curvas de bezier e isso exigiria um trabalho um pouco mais refinado sobre os pontos de controle. A vantagem das curvas é que é mais fácil usa-las em 3D, e criar superfícies.

De qualquer forma, o link que passei dá exatamente a fórmula do que você precisa. Achar a posição do centro da circunferência. Marque esse site entre seus favoritos, ali há centenas de exemplos práticos de vários processos geométricos de computação gráfica.

Criado 13 de março de 2013
Ultima resposta 5 de mai. de 2014
Respostas 7
Participantes 3