geometry

「geometry」の編集履歴(バックアップ)一覧はこちら

geometry」(2014/04/11 (金) 23:11:53) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

-点クラス 複素平面をイメージ #highlight(java){{ class P{ static final double EPS=1e-10; static int signum(double x){ return x<-EPS?-1:x>EPS?1:0; } static Comparator<P> comp = new Comparator<P>(){ public int compare(P p1, P p2) { return signum(p1.x-p2.x)!=0?signum(p1.x-p2.x):signum(p1.y-p2.y); } }; public static final P O = new P(0,0); final double x, y; P(double _x,double _y){ x=_x; y=_y; } //四則 P add(P a){ return new P(x+a.x,y+a.y); } P sub(P a){ return new P(x-a.x,y-a.y); } P mul(P a){ return new P(x*a.x-y*a.y,x*a.y+y*a.x); } P div(P a){ double d2=a.dist2(O); return new P(dot(a,this)/d2,cross(a,this)/d2); } //共役 P conj(){ return new P(x,-y); } //内積 a・b=|a||b|cosθ=a.x*b.x+a.y*b.y static double dot(P a,P b){ return a.x*b.x+a.y*b.y; } //外積 a×b=|a||b|sinθ=a.x*b.y-a.y*b.x static double cross(P a,P b){ return a.x*b.y-a.y*b.x; } //二乗距離 double dist2(P p){ return (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y); } //a,b間の距離 double dist(P p){ return sqrt(dist2(p)); } public double norm(){ return dist(O); } // a→b→cと進むときの向き static int ccw(P a,P b,P c){ b = b.sub(a); c = c.sub(a); if(cross(b,c)>EPS) return 1;//counter clockwise if(cross(b,c)<-EPS) return -1;//clockwise if(dot(b,c)<-EPS) return 2;//c--a--b on line if(b.norm()<c.norm()-EPS) return -2;//a--b--c on line return 0;//a--c--b on line (or b==c) } //oからみたaの角度 static double arg(P a,P o){ P dir=a.sub(o); double s=acos(dir.x/dir.norm()); return dir.y>0?s:2*PI-s; } //oを中心に回転 P rotate(P o,double arg){ return this.add(this.sub(o).mul(new P(cos(arg),sin(arg)))); } //→OA,→OBの面積の2倍 static double S2(P a,P b,P o){ return cross(a.sub(o),b.sub(o)); } static double S(P a,P b,P o){ return S2(a,b,o)/2; } //絶対値と偏角から座標を取得 static P polar(double abs,double arg){ return new P(abs*cos(arg),abs*sin(arg)); } // ? static P proj(P p,P o){ return o.mul(new P(dot(p,o)/o.norm(),0)); } public boolean equals(Object obj) { if(obj instanceof P){ P p=(P)obj; return signum(x-p.x)==0 && signum(y-p.y)==0; } return false; } public String toString(){ return "("+x+","+y+")"; } } }} -線クラス #highlight(java){{ //(注) //dist,isIntersectは擬似的に二項関係の演算子として扱う //intersectionはPのコンストラクタとして扱う class L extends AL{ L(P _p1, P _p2) {super(_p1, _p2);} //直線と点の距離 double dist(P p){ return abs(P.S(p2,p,p1))/p1.sub(p2).norm(); } boolean isIntersect(P p){ return abs(P.S(p2,p,p1))<EPS; } boolean isIntersect(L l){ if(isPoint() && l.isPoint())return p1.equals(l.p1); if(isPoint())return l.isIntersect(p1); if(l.isPoint())return isIntersect(l.p1); return !isParallel(l) || isIntersect(l.p1); } //垂線の足 static P FootOfLP(L l,P p){ return l.p1.add(P.proj(p.sub(l.p1),l.p2.sub(l.p1))); } //線対称な点 static P LineSymmetricLP(L l,P p){ return FootOfLP(l,p).mul(new P(2.0,0)).sub(p); } public boolean equals(Object obj) { if(obj instanceof L){ L l=(L)obj; return isParallel(l) && isIntersect(l.p1); } return false; } } //線分 class S extends AL{ S(P _p1, P _p2) {super(_p1, _p2);} boolean isIntersect(P p){//|a-p|+|p-b|<=|a-b| return p1.sub(p).norm()+p2.sub(p).norm()<=p1.sub(p2).norm()+EPS; } boolean isIntersect(L l){//l2の端点がl1の上か下か return P.cross(l.p2.sub(l.p1),p1.sub(l.p1))* P.cross(l.p2.sub(l.p1),p2.sub(l.p1))<EPS; } boolean isIntersect(S l){ return P.ccw(p1,p2,l.p1)*P.ccw(p1,p2,l.p2)<=0 && P.ccw(l.p1,l.p2,p1)*P.ccw(l.p1,l.p2,p2)<=0; } //線分と点 double dist(P p){ if(P.dot(p2.sub(p1),p.sub(p1))<EPS)return p.sub(p1).norm(); if(P.dot(p1.sub(p2),p.sub(p2))<EPS)return p.sub(p2).norm(); return abs(P.S(p2,p,p1))/p1.sub(p2).norm(); } //直線との距離 double dist(L l){ if(isIntersect(l))return 0; return min(l.dist(p1),l.dist(p2)); } //線分と線分 double dist(S l){ if(isIntersect(l))return 0; return min(min(dist(l.p1),dist(l.p2)),min(l.dist(p1),l.dist(p2))); } } abstract class AL{ //geo static final double EPS=1e-10; static int signum(double x){ return x<-EPS?-1:x>EPS?1:0; } public P p1,p2; AL(P _p1,P _p2){ p1=_p1; p2=_p2; } boolean isPoint(){ return p1.equals(p2); } // public double a(){ // P dir= p2.sub(p1); // return dir.y/dir.x; // } // public double b(){ // return P.cross(p1,p2)/(p1.x-p2.x); // } //平行 boolean isParallel(AL l){ return abs(P.cross(p2.sub(p1),l.p2.sub(l.p1)))<EPS; } //直交 boolean isOrthogonal(AL l){ return abs(P.dot(p2.sub(p1),l.p2.sub(l.p1)))<EPS; } //交点 (交差判定なし) static P intersection(AL l1,AL l2){ P dl1=l1.p2.sub(l1.p1),dl2=l2.p2.sub(l2.p1); double a=P.cross(dl2,l2.p1.sub(l1.p1)); double b=P.cross(dl2,dl1); if(abs(a)<EPS && abs(b) <EPS)return l1.p1;//same return l1.p1.add(dl1.mul(new P(a/b,0.0))); } public boolean equals(Object obj) { if(obj instanceof L){ L l=(L)obj; return this.p1.equals(l.p1) && this.p2.equals(l.p2); } return false; } public String toString(){ return p1+"-"+p2; } } }}

表示オプション

横に並べて表示:
変化行の前後のみ表示: