/**
* 功能:在二维平面上,有两个正方形,请找出一条直线,能够将这两个正方形对半分。
* 假定正方形的上下两条边与x轴平行。
*/
[java] view plain copy
- /**
- * 考虑:
- * 线的准确含义,可能性有:
- * 1)由斜率和y轴截距确定;
- * 2)由这条边上的任意两点确定;
- * 3)线段,以正方形的边作为起点和终点。
- *
- * 假设:这条线的端点应该落在正方形的边上。
- * 思路:要将两个正方形对半分,这条线必须连接两个正方形的中心点。
- */
- public class Square {
- //正方形的四条边
- int left;
- int right;
- int top;
- int bottem;
- int size;
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- }
- //得到正方形的中心点的位置
- public Point getMiddle(){
- return new Point((this.left+this.right)/2.0,(this.top+this.bottem)/2);
- }
- //返回线段mid1和mid2的线段与square2的边相交的点,即从mid1到mid2画一条线,一直延伸置碰到square2的靠外的那条边。
- public Point extend(Point mid1,Point mid2,int size){
- //确定线段mid1->mid2的方向
- int xdir=mid1.x<mid2.x?1:-1;
- int ydir=mid1.y<mid2.y?1:-1;
- //如果mid1和mid2的x坐标相同,计算斜率时,会抛出零异常,做特别处理
- if(mid1.x==mid2.y)
- return new Point(mid2.x,mid2.y+ydir*size/2.0);
- //计算线段的斜率
- double slope=(mid2.y-mid1.y)/(mid2.x-mid1.x);
- double x1=0;
- double y1=0;
- //计算相交点,注意斜率的取值
- if(Math.abs(slope)==1){
- x1=mid2.x+xdir*size/2.0;
- y1=mid2.y+ydir*size/2.0;
- }else if(Math.abs(slope)<1){
- x1=mid2.x+xdir*size/2.0;
- y1=mid2.y+slope*ydir*(size/2.0);//注意方向
- }else if(Math.abs(slope)>1){
- x1=mid2.x+slope*xdir*(size/2.0);
- y1=mid2.y+ydir*size/2.0;
- }
- return new Point(x1,y1);
- }
- public MyLine cut(Square other){
- //计算两个中心点之间的线段与正方形的边相交的位置
- Point point1=extend(this.getMiddle(),other.getMiddle(),other.size);
- Point point2=extend(this.getMiddle(),other.getMiddle(),-other.size);
- Point point3=extend(other.getMiddle(),this.getMiddle(),this.size);
- Point point4=extend(other.getMiddle(),this.getMiddle(),-this.size);
- //找出线段的起点和终点
- Point start=point1;
- Point end=point1;
- Point[] points={point1,point2,point3};
- for(int i=0;i<points.length;i++){
- if(points[i].x<start.x||points[i].x==start.x&&points[i].y<start.y)
- start=points[i];
- else if(points[i].x>end.x||points[i].x==end.x&&points[i].y>end.y)
- end=points[i];
- }
- return new MyLine(start,end);
- }
- }
- class MyLine{
- Point start;
- Point end;
- public MyLine(Point start,Point end){
- this.start=start;
- this.end=end;
- }
- }
- class Point{
- double x;
- double y;
- public Point(double x,double y){
- this.x=x;
- this.y=y;
- }
- }
或者:
public
static
double
[] getBipartition(Point[] A, Point[] B) {
// 此题由于正方形的上下两条边与x轴平行, 所以就不用直线相交去求中心点了
// 求出第一个点不同的坐标(因为点的顺序可能是混乱的)
double
p1x1 = A[
0
].x;
double
p1x2 = A[
1
].x == A[
0
].x ? A[
2
].x:A[
1
].x;
double
p1y1 = A[
0
].y;
double
p1y2 = A[
1
].y == A[
0
].y ? A[
2
].y:A[
1
].y;
// 求出第二个点不同的坐标(因为点的顺序可能是混乱的)
double
p2x1 = B[
0
].x;
double
p2x2 = B[
1
].x == B[
0
].x ? B[
2
].x:B[
1
].x;
double
p2y1 = B[
0
].y;
double
p2y2 = B[
1
].y == B[
0
].y ? B[
2
].y:B[
1
].y;
// 平分线的两个点
double
x1 = (
double
)(p1x2 + p1x1) /
2
;
double
y1 = (
double
)(p1y2 + p1y1) /
2
;
double
x2 = (
double
)(p2x1 + p2x2) /
2
;
double
y2 = (
double
)(p2y1 + p2y2) /
2
;
double
k = (
double
)(y2 - y1) / (x2 - x1);
double
b = y1 - k*x1;
return
new
double
[] {k,b};
}
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
public class Bipartition {
public double[] getBipartition(Point[] A, Point[] B) {
// write code here
double Acenterx=0;//正方形A的中心x坐标
double Acentery=0;//正方形A的中心y坐标
for(int i=0;i<4;i++){
Acenterx+=A[i].x;
Acentery+=A[i].y;
}
Acenterx/=4.0;
Acentery/=4.0;
double Bcenterx=0;//正方形B的中心x坐标
double Bcentery=0;//正方形B的中心y坐标
for(int i=0;i<4;i++){
Bcenterx+=B[i].x;
Bcentery+=B[i].y;
}
Bcenterx/=4.0;
Bcentery/=4.0;
double[] result=new double[2];
result[0]=(Bcentery-Acentery)/(Bcenterx-Acenterx);//求斜率
result[1]=Acentery-result[0]*Acenterx;//求截距
return result;
}
}