Newer
Older
Zemi01 / src / main / java / info / istlab / Zemi01 / miuramath / CopyOfGraphPanel.java
@motoki miura motoki miura on 21 Jan 2023 6 KB 数学関連
package info.istlab.Zemi01.miuramath;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class CopyOfGraphPanel extends JPanel implements MouseListener, MouseMotionListener {

	private static final long serialVersionUID = -919448575666487391L;
	public static JFrame jf;
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		jf = new JFrame("GraphPanel");
		jf.getContentPane().add(new CopyOfGraphPanel());
		jf.pack();
		jf.setVisible(true);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	Point2D offset;

	ArrayList<Point2D> points;
	Dimension dim;
	Point2D pointingPmath;
	Point2D pressP;
	int psize = 10;
	int zoom = 20;
	int gridgap = 1;

	Point2D cursorsnapCandidate; //カーソル位置のスナッピング

	public Dimension getPreferredSize(){
		return dim;
	}

	public CopyOfGraphPanel(){
		offset = new Point2D.Double(0,0);

		points = new ArrayList<Point2D>();
		dim = new Dimension(500,400);
		addMouseListener(this);
		addMouseMotionListener(this);
		points.add(new Point2D.Double(2,1));
		points.add(new Point2D.Double(5,7));
		setBackground(Color.white);
		setForeground(Color.black);
	}
	public void paint(Graphics g){
		paintComponent(g);
	}
	public void paintComponent(Graphics g){
		Graphics2D g2d = (Graphics2D)g;
		RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setRenderingHints(rh);

		//		g2d.setBackground(Color.white);
		//		g2d.setColor(Color.black);
		g2d.clearRect(0,0,getWidth(),getHeight());

		paintGrid(g2d);

		for(Point2D p:points){
			paintPoint(g2d, p);
			//			g2d.fillOval((int)p.getX()-psize/2, (int)p.getY()-psize/2, psize, psize);
			//			g2d.drawString(String.valueOf(num), (int)p.getX()+10, (int)p.getY());
		}

		if (pointingPmath != null){
			g2d.setColor(Color.red);
			paintPoint(g2d, pointingPmath);
		}

		//		updateRegLine();
		paintLagrange(g2d);

		//		g2d.setColor(Color.blue);
		//		g2d.drawString("a = "+String.valueOf(a), (int)(-getWidth()/2+10-offset.getX()), (int)(-getHeight()/2+20-offset.getY()));
		//		g2d.drawString("b = "+String.valueOf(b), (int)(-getWidth()/2+10-offset.getX()), (int)(-getHeight()/2+35-offset.getY()));
		paintCursorSnap(g2d);
	}
	public void paintCursorSnap(Graphics2D g2d){
		if (cursorsnapCandidate != null){
			g2d.setColor(new Color(250,130,130));
			g2d.fillOval((int)(cursorsnapCandidate.getX()*zoom-psize/2),
					(int)(-(cursorsnapCandidate.getY()*zoom+psize/2)), psize, psize);
		}
	}

	public void paintGrid(Graphics2D g2d){
		g2d.setColor(new Color(230,230,230));

		g2d.translate(getWidth()/2+offset.getX(), getHeight()/2+offset.getY());
		//		System.out.println(g2d.getTransform().getTranslateX()+" "+g2d.getTransform().getTranslateY());

		for(int i=0;i<getWidth();i+=(gridgap*zoom)){
			g2d.drawLine(i, -getHeight(), i, getHeight());
			g2d.drawLine(-i, -getHeight(), -i, getHeight());
		}
		for(int i=0;i<getHeight();i+=(gridgap*zoom)){
			g2d.drawLine(-getWidth(),i,getWidth(),i);
			g2d.drawLine(-getWidth(),-i,getWidth(),-i);
		}
		g2d.setColor(Color.black);
		g2d.drawLine(0, getHeight()*3, 0, -getHeight()*3);
		g2d.drawLine(-getWidth()*3, 0, getWidth()*3, 0);

		//		g2d.translate(-(getWidth()/2+offset.getX()), -(getHeight()/2+offset.getY()));
	}
	public void paintPoint(Graphics2D g2d, Point2D p){
		g2d.fillOval((int)(p.getX()*zoom-psize/2),
				(int)(-(p.getY()*zoom+psize/2)), psize, psize);
		//		g2d.drawString(String.valueOf(num), (int)p.getX()+10, (int)p.getY());
	}
	public void paintLagrange(Graphics2D g2d){
		Point2D prep = null;
		for(double x=-getWidth()/2-offset.getX(); x<getWidth()/2-offset.getX(); x+=2.0/zoom){
			double sum = 0;
			for(int k=0;k<points.size();k++){
				
				double f = points.get(k).getY();
				sum += f*Lk(k,x);
			}
			Point2D p1 = math2scr(new Point2D.Double(x,sum));	
			if (prep == null) prep = p1;
			g2d.drawLine((int)p1.getX(), (int)p1.getY(), (int)prep.getX(), (int)prep.getY());
			prep = p1;
		}
	}
	public double Lk(int k, double x){
		double xk = points.get(k).getX();
		double up=1.0, down=1.0;
		for(int i=0;i<points.size();i++){
			if (i != k){
				up *= (x - points.get(i).getX());
				down *= (xk - points.get(i).getX());
			}
		}
		return up/down;
	}
	public Point2D scr2math(Point2D p){
		double x = p.getX() ;
		double y = p.getY() ;
		x = x - offset.getX() - getWidth()/2 ;
		y = y - offset.getY() - getHeight()/2 ;
		y = -y;
		//		System.out.println("scr2math "+x+", "+y);
		return new Point2D.Double(x/zoom,y/zoom);
	}
	public Point2D math2scr(Point2D p){
		return new Point2D.Double(p.getX()*zoom, -p.getY()*zoom);
	}

	public void mouseClicked(MouseEvent e) {
		if (e.getButton()==3){
			Point2D pointing = findPointing(e.getPoint());
			if (pointing == null) points.add(snap(scr2math(e.getPoint())));
			else {
				if (points.size()>2)
					points.remove(pointing);
			}
			repaint();
		}
	}
	public void mouseEntered(MouseEvent e) {
	}
	public void mouseExited(MouseEvent e) {
	}
	public Point2D findPointing(Point2D mp){
		Point2D nearest = null;
		Point2D mPmath = scr2math(mp);
		for(Point2D p: points){
			if (mPmath.distance(p) < 1){
				nearest = p;
			}
		}
		return nearest;
	}
	public void mousePressed(MouseEvent e) {
		pressP = e.getPoint();
		Point2D pressPmath = snap(scr2math(pressP));
		Point2D nearest = null;
		for(Point2D p: points){
			if (pressPmath.distance(p) < 1){
				nearest = p;
			}
		}
		pointingPmath = nearest;
		repaint();
	}
	public void mouseReleased(MouseEvent e) {
		pointingPmath = null;
		repaint();
	}
	public void mouseDragged(MouseEvent e) {
		if (pointingPmath != null){
			pointingPmath.setLocation(snap(scr2math(e.getPoint())));
			cursorsnapCandidate = null;
			repaint();
		} else {
			//			e.translatePoint((int)offset.getX(), (int)offset.getY());
			offset.setLocation(offset.getX()+(e.getPoint().getX()-pressP.getX()),
					offset.getY()+(e.getPoint().getY()-pressP.getY()));
			pressP = e.getPoint();
			repaint();
		}
	}
	public void mouseMoved(MouseEvent e) {
		Point2D p = snap(scr2math(e.getPoint()));
		cursorsnapCandidate = p;
		System.out.println(p.toString());
		repaint();
	}
	public Point2D snap(Point2D p){
		double pixel = gridgap;
		double px = p.getX();
		double py = p.getY();
		System.out.println(px+" "+py);
		return new Point2D.Double((int)(px/pixel)*pixel, (int)(py/pixel)*pixel);
	}
	//	void logappend(String s){
	//		jta.append(s+"\n");
	//		jta.setCaretPosition(jta.getDocument().getLength());
	//	}

}