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 里面实现以上几个程序!

最好是完整的代码阿!急急急!

会有点小BUG:我这里只是示范了用鼠标点击 使得一个圆移动位置 其他都写在main函数里 你的getDistance()方法我实在不知道你什么意思。。。
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个圆。已知这些圆两两没有交点,即两圆的关系只存在相离和包含。求这些圆的异或面

   积并。异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑。
Input

   第一行包含一个正整数N,代表圆的个数。接下来N行,每行3个非负整数x,y,r,表示一个圆心在(x,y),半径为r的

圆。保证|x|,|y|,≤10^8,r>0,N<=200000
Output

   仅一行一个整数,表示所有圆的异或面积并除以圆周率Pi的结果。

Sample Input
  2
  0 0 1
  0 0 2

Sample 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,24

 

             因此,一个圆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个圆的问题的主要内容,如果未能解决你的问题,请参考以下文章

判断2圆的位置关系

Bzoj4561 [JLoi2016]圆的异或并

空间三点圆心计算公式

BZOJ4561[JLoi2016]圆的异或并 扫描线

计数方法(扫描线):JLOI 2016 圆的异或并

在百度地图中,已知圆的圆心坐标、 和圆的半径(单位:米),怎么计算圆的坐标范围?