Java 坐标内2点做2个圆的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 坐标内2点做2个圆的问题相关的知识,希望对你有一定的参考价值。
要做6个小程序
1.定义两个圆每个圆的属性
2.在getDiameter的程序中算出每个圆的直径
3.在move 的程序中让每个圆移动到新的坐标点上
4.在getDistance 的程序中计算 圆与圆之前的距离(不是圆心的,圆和圆之前)
5.在hasintersection程序中检验2个圆是否相交
6。在smaller中比较2个圆的大小
最后在main 里面实现以上几个程序!
最好是完整的代码阿!急急急!
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
/*
* Classname: drawyuan.java
*
* Author: zenglulin
*
* Version information: V1.0
*
* Date: 2010-6-7
*
* Copyright notice: Copyright (c) 2009, Openmobi Co.Ltd. All rights reserved.
*
* Description: TODO
*/
/**
* @author zenglulin
*
*/
public class drawyuan
/**
*
*/
public drawyuan()
// TODO Auto-generated constructor stub
/**
* TODO
* @param args
* return: void
* author: zenglulin
* time: 上午10:11:33
*/
public static void main(String[] args)
// TODO Auto-generated method stub
MyFrame frame = new MyFrame("yuanceshi");
frame.Yuan1.move(frame.p3);
frame.Yuan2.move(frame.p4); //程序里直接移动
System.out.println("圆1的直径是:" + frame.Yuan1.getDiameter());
System.out.println("圆2的直径是:" + frame.Yuan2.getDiameter());
if(frame.Yuan1.hasintersection(frame.Yuan2))
System.out.println("圆1和圆2相交");
else
System.out.println("圆1和圆不相交");
if(frame.Yuan1.smaller(frame.Yuan2) < 0)
System.out.println("圆1比圆2小 ");
else if(frame.Yuan1.smaller(frame.Yuan2) > 0)
System.out.println("圆1比圆2大 ");
else
System.out.println("圆1和圆2大小相等 ");
class MyFrame extends JFrame
/* serialVersionUID: long*/
private static final long serialVersionUID = 1L;
public MyFrame(String title)
super(title);
init();
JPanel p =new JPanel();
Container c = getContentPane();
c.add(p);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//点击鼠标移动圆
addMouseListener(new MouseAdapter()
public void mousePressed(MouseEvent event)
Point p = event.getPoint();
Yuan1.move(p);
if(Yuan1.hasintersection(Yuan2))
System.out.println("圆1和圆2相交");
else
System.out.println("圆1和圆不相交");
repaint();
// validate();
);
setSize(200, 100);
d = getSize();
p3 = new Point(61, d.height /2 + 10 );
p4 = new Point(105, d.height /2+ 10);
setVisible(true);
repaint();
validate();
public void init()
p1 = new Point(30, 30);
p2 = new Point(95, 30);
r1 = 20;
r2 = 25;
Yuan1 = new Yuan(p1, r1);
Yuan2 = new Yuan(p2, r2);
public void update(Graphics g)
Yuan1.draw(g);
Yuan2.draw(g);
public void paint(Graphics g)
super.paintComponents(g);
Yuan1.draw(g);
Yuan2.draw(g);
Point p1,p2,p3,p4;
int r1,r2;
Yuan Yuan1,Yuan2;
Dimension d;
class Yuan
public Yuan(Point p, int r)
this.point = p;
this.radius = r;
private int radius; //半径
public int getRadius()
return radius;
public void setRadius(int radius)
this.radius = radius;
public Point getPoint()
return point;
public void setPoint(Point point)
this.point = point;
public void move(Point point)
setPoint(point);
/**
* TODO 我不知道你说的这个距离是什么意思
* @param other
* @return
* return: int
* author: zenglulin
* time: 上午10:26:45
*/
public int getDistance (Yuan other)
return 0;
public boolean hasintersection(Yuan other)
return (int)getPoint().distance(other.getPoint())
< radius + other.getRadius();
public int getDiameter() //获得直径
return 2* radius;
/**
* TODO 比较大小
* @param other
* @return
* return: int -1 当前圆更小 1--当前圆更大 0 相等
* author: zenglulin
* time: 上午10:27:21
*/
public int smaller(Yuan other)
// TODO Auto-generated method stub
if(radius < other.getRadius())
return -1;
else if(radius > other.getRadius())
return 1;
else
return 0;
public void draw(Graphics g)
g.drawOval((int)point.getX() - radius, (int)point.getY() - radius, 2*radius, 2*radius);
private Point point; //圆心坐标点
参考技术A /**
* 圆对象
* @author Shurrik
*
*/
public class Circular
private String name;
private int r;
private int x;
private int y;
/**
* 构造方法1
* @param name
* 圆的名字
* @param r
* 圆的半径
* @param x
* 圆形横坐标
* @param y
* 圆形纵坐标
*/
public Circular(String name, int r, int x, int y)
this.name = name;
this.r = r;
this.x = x;
this.y = y;
/**
* 构造方法2
* @param name
* 圆的名字
* @param r
* 圆的半径
*/
public Circular(String name, int r)
this.name = name;
this.r = r;
this.x = r;
this.y = r;
public String getName()
return name;
public void setName(String name)
this.name = name;
public int getR()
return r;
public void setR(int r)
this.r = r;
public int getX()
return x;
public void setX(int x)
this.x = x;
public int getY()
return y;
public void setY(int y)
this.y = y;
-------------------------------------------------
import java.awt.Graphics;
import javax.swing.JPanel;
/**
* 画布对象
* @author Shurrik
*
*/
public class MyPanel extends JPanel
private Circular c1;
private Circular c2;
private int distance = -1;
public MyPanel(Circular c1, Circular c2)
this.c1 = c1;
this.c2 = c2;
public void paint(Graphics g)
g.drawOval(c1.getX() - c1.getR(), c1.getY() - c1.getR(), this
.getDiameter(c1), this.getDiameter(c1));
g.drawLine(c1.getX(), c1.getY(), c2.getX(), c2.getY());
g.drawOval(c2.getX() - c2.getR(), c2.getY() - c2.getR(), this
.getDiameter(c2), this.getDiameter(c2));
/**
* 计算圆的直径
*
* @param c
* 圆对象
* @return 指定圆的直径
*/
public int getDiameter(Circular c)
int diameter = c.getR() * 2;
return diameter;
/**
* 移动指定圆到指定位置
*
* @param c
* 圆对象
* @param x
* 目标位置横坐标
* @param y
* 目标位置纵坐标
*/
public void move(Circular c, int x, int y)
c.setX(x);
c.setY(y);
this.repaint();
/**
* 计算圆与圆之前的距离
* @param c1 圆对象c1
* @param c2 圆对象c2
* @return 两个圆之间的距离(边与边)
*/
public int getDistance(Circular c1, Circular c2)
distance = (int) Math.sqrt((c1.getX() - c2.getX())
* (c1.getX() - c2.getX()) + (c1.getY() - c2.getY())
* (c1.getY() - c2.getY()));
distance = distance - c1.getR() - c2.getR();
return distance;
/**
* 检验2个圆是否相交
* @param c1 圆对象c1
* @param c2 圆对象c2
* @return true相交,false不相交
*/
public boolean hasintersection(Circular c1, Circular c2)
this.getDistance(c1, c2);
if(distance<=0)
return true;
else
return false;
/**
* 判断圆c1是否比c2小
* @param c1 圆对象c1
* @param c2 圆对象c2
* @return true:c1比c2小,false:相等或者c1比c2大
*/
public boolean smaller(Circular c1, Circular c2)
if(c1.getR()<c2.getR())
return true;
else
return false;
-------------------------------------------------
import java.awt.Toolkit;
import javax.swing.JFrame;
/**
* 界面对象
* @author Shurrik
*
*/
public class MainFrame extends JFrame
private MyPanel display;
private int swidth = Toolkit.getDefaultToolkit().getScreenSize().width;
private int sheight = Toolkit.getDefaultToolkit().getScreenSize().height;
private int fwidth = 500;
private int fheight = 500;
public MainFrame(MyPanel display)
this.display = display;
this.add(display);
this.setBounds((swidth-fwidth)/2, (sheight-fheight)/2, fwidth, fheight);
this.setResizable(false);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//程序入口
public static void main(String[] args)
Circular c1 = new Circular("A",40);
Circular c2 = new Circular("B",70,100,250);
MyPanel display = new MyPanel(c1,c2);
new MainFrame(display);
System.out.println("圆"+c1.getName()+"的直径是:"+display.getDiameter(c1));
System.out.println("圆"+c2.getName()+"的直径是:"+display.getDiameter(c2));
display.move(c1, 160, 100);
display.move(c2, 200, 120);
System.out.println("圆"+c1.getName()+"和圆"+c2.getName()+"之间的距离是:"+display.getDistance(c1, c2));
if(display.hasintersection(c1, c2))
System.out.println("圆"+c1.getName()+"和圆"+c2.getName()+"相交");
else
System.out.println("圆"+c1.getName()+"和圆"+c2.getName()+"不相交");
-------------------------------------------------
没写事件,需要什么事件你自己加吧。鼠标放方法提上看方法说明,很详细的。
2个圆之间的距离,是否相交都写好了。!本回答被提问者采纳
BZOJ4561:圆的异或并(扫描线+set||splay||线段树)
在平面直角坐标系中给定N个圆。已知这些圆两两没有交点,即两圆的关系只存在相离和包含。求这些圆的异或面
第一行包含一个正整数N,代表圆的个数。接下来N行,每行3个非负整数x,y,r,表示一个圆心在(x,y),半径为r的
仅一行一个整数,表示所有圆的异或面积并除以圆周率Pi的结果。
Sample InputSample Output
3
思路:扫描线,有很多这样的题,思路就是分成上下两半圆,然后用数据结构。
前提是不相交。然后可以求出包含关系。
具体:把一个圆分为上下两个半圆,然后每次扫描线扫到一个圆X(左边),去找这个圆的“上面的第一个半圆Cir”,若Cir是上半圆的话,则X被其包含,否则无。 然后把圆X加入数据结构中。
扫描到一个圆X(右边),则把圆X从数据结构中删除。
对于当前扫描线里的圆(保存在数据结构里的那些),排序是根据直线与圆的交点的纵坐标排序得到:
下面左图,B上面第一个圆是A,因为3上面第一个点是2。而2代表下半圆,说明无圆包含B。
下图右图,B上面第一个圆是A,因为3上面第一个点是1。而1代表上半圆,说明第一个包含B的是A。(可能A还被其他圆包含,即B<A<...)
简单证明划分圆来解决的可行性:
由于圆之间不相交,所以我们用平行Y轴是直线去扫描的时候(从左向右),直线与圆产生一些交点。
易得:这些圆中,一个圆与直线的两个交点与其他圆的两个交点不交叉。即一对交点“属于哪个圆”这个属性“相离”或者“包含”,不会“交叉”,如下:
如左图:A圆与直线交点1,2,B圆与直线交点3,4。二圆相离,所以(1,2),(3,4)。
如右图:A圆与直线交点1,2,B圆与直线交点3,4。二圆包含。所以(1,(3,4)2)。
不会出现下图中的(1,(3,2)4)
因此,一个圆X被圆Y包含,要求最内层的Y,只需要在这条线上找X与直线的交点a上面的第一个“下半圆交点”即可。
-----------------------上面是简单证明,下面是整正题--------------------------
数据结构用于查找大于等于a的数,可以是set,线段树,判平衡树等。
这里是练习平衡树,但是为了保险,先写了下set,不然直接写splay找错很麻烦。
待续。。。。
#include<set> #include<cmath> #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int maxn=200010; struct cir{ ll x,y,r; cir(){} cir(ll xx,ll yy,ll rr):x(xx),y(yy),r(rr){} }c[maxn]; struct ins{ int x,opt,id; ins(){} ins(int xx,int oo,int ii):x(xx),opt(oo),id(ii){} }w[maxn<<1];= ll Lx,sig[maxn]; set<ins>s; ll cal(ll x) { return x*x; } bool cmp(ins a,ins b){ return a.x<b.x; } bool operator <(ins a,ins b){ double y1=c[a.id].y+a.opt*sqrt(cal(c[a.id].r)-cal(c[a.id].x-Lx)); double y2=c[b.id].y+b.opt*sqrt(cal(c[b.id].r)-cal(c[b.id].x-Lx)); if(y1==y2) return a.opt<b.opt; //当一个圆的左顶点刚好在LX线上? return y1<y2; } int main() { int N; scanf("%d",&N); for(int i=1;i<=N;i++){ scanf("%lld%lld%lld",&c[i].x,&c[i].y,&c[i].r); w[(i<<1)-1]=ins(c[i].x-c[i].r,1,i); w[i<<1]=ins(c[i].x+c[i].r,-1,i); } sort(w+1,w+(N<<1)+1,cmp); for(int i=1;i<=(N<<1);i++){ Lx=w[i].x; if(w[i].opt==1){//左,加圆 set<ins>::iterator it; it=s.upper_bound(ins(0,1,w[i].id)); if(it==s.end()) sig[w[i].id]=1; else{ if((*it).opt==-1) sig[w[i].id]=sig[(*it).id]; else sig[w[i].id]=-sig[(*it).id]; } s.insert(ins(0,1,w[i].id)); s.insert(ins(0,-1,w[i].id)); } else { s.erase(ins(0,1,w[i].id)); s.erase(ins(0,-1,w[i].id)); } } ll ans=0; for(int i=1;i<=N;i++) ans+=sig[i]*cal(c[i].r); printf("%lld\\n",ans); return 0; }
以上是关于Java 坐标内2点做2个圆的问题的主要内容,如果未能解决你的问题,请参考以下文章