public bool contains(LDPoint p) { var a = this.normalized(); return a.left() <= p.x() && a.right() >= p.x() && a.top() <= p.y() && a.bottom() >= p.y(); }
public LDRect(LDPoint topleft, LDPoint bottomRight) { this.xp = topleft.x(); this.yp = topleft.y(); this.w = bottomRight.x() - topleft.x(); this.h = bottomRight.y() - topleft.y(); }
/// <summary> /// /// </summary> /// <param name="l"></param> /// <param name="point"></param> /// <returns></returns> public IntersectType intersect(LDLine l, out LDPoint point) { LDPoint pointA = this.pt1; LDPoint pointB = this.pt2; LDPoint pointC = l.pt1; LDPoint pointD = l.pt2; float dBunbo = (pointB.x() - pointA.x()) * (pointD.y() - pointC.y()) - (pointB.y() - pointA.y()) * (pointD.x() - pointC.x()); if (0 == dBunbo) { // 平行 point = null; return(IntersectType.NoIntersection); } //ここで交点を導出 LDPoint vectorAC = pointC - pointA; var dR = ((pointD.y() - pointC.y()) * vectorAC.x() - (pointD.x() - pointC.x()) * vectorAC.y()) / dBunbo; var dS = ((pointB.y() - pointA.y()) * vectorAC.x() - (pointB.x() - pointA.x()) * vectorAC.y()) / dBunbo; point = pointA + dR * (pointB - pointA); return((new LDRect(pointA, pointB)).contains(point) && (new LDRect(pointC, pointD)).contains(point) ? IntersectType.BoundedIntersection : IntersectType.UnboundedIntersection); /* * IntersectType intersect; * if (MathFunctions.uFuzzyCompare(this.angle(), l.angle())) * { * point = null; * intersect = IntersectType.NoIntersection; * } * else * { * LDLine lp12 = new LDLine(this.pt1, l.pt1); * LDLine lp22 = new LDLine(this.pt1, l.pt2); * * LDLine lp11 = new LDLine(l.pt1, this.pt1); * LDLine lp21 = new LDLine(l.pt1, this.pt2); * * if (((this.angleTo(lp12) - 180f) * (this.angleTo(lp22) - 180f) < 0) * && ((this.angleTo(lp11) - 180f) * (this.angleTo(lp21) - 180f) < 0)) * { * point = null; * intersect = IntersectType.BoundedIntersection; * } * else * { * point = null; * intersect = IntersectType.UnboundedIntersection; * } * } * return intersect; */ }
public static double crossProductValue(LDPoint pa, LDPoint pb, LDPoint pc) { // 有向線分 (pa,pb), (pa,pc) の外積の z 成分を求める double n = pb.x() * (pa.y() - pc.y()) + pa.x() * (pc.y() - pb.y()) + pc.x() * (pb.y() - pa.y()); return(n); }
public static LDPoint rotatePoint(LDPoint origin, LDPoint pt, ld_float rad) { LDPoint tmp = pt - origin; float x = (float)(tmp.x() * Math.Cos(rad) + tmp.y() * Math.Sin(rad)); float y = ((float)(-tmp.x() * Math.Sin(rad) + tmp.y() * Math.Cos(rad))); return(new LDPoint(x + origin.x(), y + origin.y())); }
/* * public static T lerp2D<T>(T from1, T to1, double t1, T from2, T to2, double t2) * { * T tmp1 = (1 - t1) * from1 + t1 * to1; * T tmp2 = (1 - t1) * from2 + t1 * to2; * return (1 - t2) * tmp1 + t2 * tmp2; * } */ #endregion #region inverseLerp2D /* C#では使用できない ジェネリクスと値間の演算 * public static void inverseLerp2D<T>(T from1, T to1, T from2, T to2, T value, out double t1, out double t2) * { * // 参考 stackoverflow "Inverse Bilinear Interpolation?" * // http://stackoverflow.com/questions/808441/inverse-bilinear-interpolation * // p2 --- p3 * // | | * // t | p | * // | | * // p0 --- p1 * // s * // A = (p0-p) X (p0-p2) * // B = ( (p0-p) X (p1-p3) + (p1-p) X (p0-p2) ) / 2 * // C = (p1-p) X (p1-p3) * // s = ( (A-B) +- sqrt(B^2 - A*C) ) / ( A - 2*B + C ) * * double a = crossProductValue(from2 - value, from2 - from1); * double b = (crossProductValue(from2 - value, to2 - to1) + crossProductValue(to2 - value, from2 - from1)) / 2; * double c = crossProductValue(to2 - value, to2 - to1); * * double d = (a - 2 * b + c); * * if (d == 0 || Math.Abs(d) < 0.0001) * { * t1 = a / (a - c); * // qDebug()<<"d==0"<<t1; * } * else * { * t1 = ((a - b) + Math.Sqrt(b * b - a * c)) / d;//NOTE:ここに入ると変換の形状が壊れる * // qDebug()<<"d!=0"<<t1<<"or"<<((a-b)-sqrt(b*b-a*c))/d; * } * * // t = ( (1-s)*(x0-x) + s*(x1-x) ) / ( (1-s)*(x0-x2) + s*(x1-x3) ) * // t2=((1-t1)*(from2.y()-value.y())+t1*(to2.y()-value.y())) / ((1-t1)*(from2.y()-from1.y())+t1*(to2.y()-to1.y())); * LDPoint tmp1 = ((1 - t1) * (from2 - value) + t1 * (to2 - value)); * LDPoint tmp2 = ((1 - t1) * (from2 - from1) + t1 * (to2 - to1)); * * * Util.uAssert(!(tmp2.x() == 0 && tmp2.y() == 0)); * * if (tmp2.x() == 0 && tmp2.y() != 0) * { * t2 = tmp1.y() / tmp2.y(); * } * else //if(tmp2.y()==0&&tmp2.x()!=0) * { * t2 = tmp1.x() / tmp2.x(); * } * // else * // { * // LDPoint tmp(tmp1.x()/tmp2.x(),tmp1.y()/tmp2.y()); * // t2=tmp.x()+tmp.y()/2; * //// t2=sqrt(tmp.x()*tmp.x()+tmp.y()*tmp.y()); * // } * * t2 = 1 - t2; * } */ public static void inverseLerp2D(LDPoint from1, LDPoint to1, LDPoint from2, LDPoint to2, LDPoint value, out double t1, out double t2) { // 参考 stackoverflow "Inverse Bilinear Interpolation?" // http://stackoverflow.com/questions/808441/inverse-bilinear-interpolation // p2 --- p3 // | | // t | p | // | | // p0 --- p1 // s // A = (p0-p) X (p0-p2) // B = ( (p0-p) X (p1-p3) + (p1-p) X (p0-p2) ) / 2 // C = (p1-p) X (p1-p3) // s = ( (A-B) +- sqrt(B^2 - A*C) ) / ( A - 2*B + C ) double a = crossProductValue(from2 - value, from2 - from1); double b = (crossProductValue(from2 - value, to2 - to1) + crossProductValue(to2 - value, from2 - from1)) / 2; double c = crossProductValue(to2 - value, to2 - to1); double d = (a - 2 * b + c); if (d == 0 || Math.Abs(d) < 0.0001) { t1 = a / (a - c); // qDebug()<<"d==0"<<t1; } else { t1 = ((a - b) + Math.Sqrt(b * b - a * c)) / d; //NOTE:ここに入ると変換の形状が壊れる // qDebug()<<"d!=0"<<t1<<"or"<<((a-b)-sqrt(b*b-a*c))/d; } // t = ( (1-s)*(x0-x) + s*(x1-x) ) / ( (1-s)*(x0-x2) + s*(x1-x3) ) // t2=((1-t1)*(from2.y()-value.y())+t1*(to2.y()-value.y())) / ((1-t1)*(from2.y()-from1.y())+t1*(to2.y()-to1.y())); LDPoint tmp1 = ((1 - (float)t1) * (from2 - value) + (float)t1 * (to2 - value)); LDPoint tmp2 = ((1 - (float)t1) * (from2 - from1) + (float)t1 * (to2 - to1)); Debug.Assert(!(tmp2.x() == 0 && tmp2.y() == 0)); if (tmp2.x() == 0 && tmp2.y() != 0) { t2 = tmp1.y() / tmp2.y(); } else //if(tmp2.y()==0&&tmp2.x()!=0) { t2 = tmp1.x() / tmp2.x(); } // else // { // LDPoint tmp(tmp1.x()/tmp2.x(),tmp1.y()/tmp2.y()); // t2=tmp.x()+tmp.y()/2; //// t2=sqrt(tmp.x()*tmp.x()+tmp.y()*tmp.y()); // } t2 = 1 - t2; }
public LDPoint transform(LDPoint p) { float rx = p.x() * (float)Math.Cos(rotate) - p.y() * (float)Math.Sin(rotate); float ry = p.x() * (float)Math.Sin(rotate) + p.y() * (float)Math.Cos(rotate); float x = rx * scale + originX; float y = ry * scale + originY; return(new LDPoint(x, y)); }
/// <summary> /// TODO: LDPoint注意 /// </summary> /// <param name="pt"></param> /// <param name="clip"></param> /// <returns></returns> public LDPoint inverseTransform(LDPoint pt, bool clip = false) { if (getColumn() == 0 && getRow() == 0) { //メッシュがない場合はそのままの値を返す return(pt); } double x = pt.x(); double y = pt.y(); //Gridからマッピング先のQuadを見つける LDPoint index = getMapedQuadIndex(new LDPoint((float)x, (float)y)); int col = (int)index.x(); int row = (int)index.y(); if (clip) { //Grid内にClipする。QuadをClipして変換するのではない col = LDMathUtil.clamp(col, 0, getColumn()); row = LDMathUtil.clamp(row, 0, getRow()); } LDPoint local = new LDPoint(); if (isOutside(row, col)) { LDQuadTransform quad = createOutsideQuadTransform(row, col); return(quad.inverseTransform(pt, clip)); //TODO:到達しない場所あります local = quad.inverseTransform(pt, clip); LDPoint _internal; _internal.setX((col + 1) * (1.0f / (getColumn() + 2)) + local.x() / (getColumn() + 2)); _internal.setY((row + 1) * (1.0f / (getRow() + 2)) + local.y() / (getRow() + 2)); LDQuadTransform tmp = new LDQuadTransform(new LDPoint(-1, -1), new LDPoint(getColumn() + 1, getRow() + 1)); return(tmp.transform(_internal)); } else { LDQuadTransform quad = getQuadTransform(row, col); local = quad.inverseTransform(pt, clip); LDPoint _internal = new LDPoint(); _internal.setX(col * (1.0f / getColumn()) + local.x() / getColumn()); _internal.setY(row * (1.0f / getRow()) + local.y() / getRow()); return(_internal); } }
public LDPoint getQuadIndex(LDPoint t) { double tx = t.x(); double ty = t.y(); // Debug.Assert( tx>=0 ); // Debug.Assert( tx<=1 ); // Debug.Assert( ty>=0 ); // Debug.Assert( ty<=1 ); int row, col; if (tx == 1) { col = getColumn() - 1; } else { col = (int)Math.Truncate(tx * getColumn()); } if (ty == 1) { row = getRow() - 1; } else { row = (int)Math.Truncate(ty * getRow()); } return(new LDPoint(col, row)); }
public LDRect(LDPoint topleft, LDSize size) { this.xp = topleft.x(); this.yp = topleft.y(); this.w = size.width(); this.h = size.height(); }
public static double crossProductValue(LDPoint pa, LDPoint pb) { // pa と pb の外積の z 成分を求める double n = pa.x() * pb.y() - pa.y() * pb.x(); return(n); }
public LDPoint transform(LDPoint p) { LDVector3 srcVec = new LDVector3(p.x(), p.y(), 0); LDVector3 dstVec = m_matrix.transform(srcVec); return(new LDPoint(dstVec.x, dstVec.y)); }
public void transformTest() { { LDQuadTransform quad = new LDQuadTransform(new LDPoint(10, 10), new LDPoint(30, 30)); LDPoint src = new LDPoint(0.5f, 0.25f); LDPoint dst = new LDPoint(); dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 20.0); TestUtil.COMPARE(dst.y(), 15.0); } { LDQuadTransform quad = new LDQuadTransform(new LDPoint(10, 10), new LDPoint(20, 10), new LDPoint(100, 100), new LDPoint(10, 20)); LDPoint src = new LDPoint(0.9f, 0.9f); LDPoint dst = new LDPoint(); dst = quad.transform(src); // TestUtil.COMPARE(dst.x(),83.8); // TestUtil.COMPARE(dst.y(),83.8); TestUtil.LDFUZZY_COMPARE(dst.x(), 83.8, 0.0000001); TestUtil.LDFUZZY_COMPARE(dst.y(), 83.8, 0.0000001); // TestUtil.LDFUZZY_COMPARE(dst.x(),83,0.001); // TestUtil.LDFUZZY_COMPARE(dst.y(),83,0.001); } }
public static LDPoint scalePoint(LDPoint origin, LDPoint pt, ld_float scale_x, ld_float scale_y) { LDPoint tmp = pt - origin; float x = tmp.x() * scale_x; float y = tmp.y() * scale_y; return(new LDPoint(x + origin.x(), y + origin.y())); }
public LDPoint inverseTransform(LDPoint pt) { float sx = (pt.x() - originX) / scale; float sy = (pt.y() - originY) / scale; float rx = sx * (float)Math.Cos(-rotate) - sy * (float)Math.Sin(-rotate); float ry = sx * (float)Math.Sin(-rotate) + sy * (float)Math.Cos(-rotate); return new LDPoint(rx, ry); }
public LDPoint inverseTransform(LDPoint pt) { float sx = (pt.x() - originX) / scale; float sy = (pt.y() - originY) / scale; float rx = sx * (float)Math.Cos(-rotate) - sy * (float)Math.Sin(-rotate); float ry = sx * (float)Math.Sin(-rotate) + sy * (float)Math.Cos(-rotate); return(new LDPoint(rx, ry)); }
public LDQuadTransform(LDPoint topLeft, LDPoint bottomRight) { m_topLeft = topLeft; m_bottomRight = bottomRight; m_topRight.setX(bottomRight.x()); m_topRight.setY(topLeft.y()); m_bottomLeft.setX(topLeft.x()); m_bottomLeft.setY(bottomRight.y()); }
private LDPoint getCalcAddVertex(LDPoint uv) { LDPoint calcAddVertex = new LDPoint(-1, -1); //とりあえず -1,-1で初期化 if (m_points.size() == 0) //最初の頂点がなければuvと同じ座標位置にformをする { calcAddVertex = new LDPoint(0, 0); } else if (m_points.size() == 1) //頂点数が一つだけならばその座標を原点としてuvと同じ比率の座標をformにする { LDPoint p0 = m_points.at(0); calcAddVertex = new LDPoint(p0.x() + uv.x(), p0.y() + uv.y()); } // else if ( m_points.size()==2 )// NOTE 計算あまり検証していない // { // //uvと頂点の縮尺を計算 // float scale_x=0; // if ( ( m_uvMap[1].x()-m_uvMap[0].x() )==0 ) // { // scale_x=1; // } // else // { // scale_x=( m_points[1].x()-m_points[0].x() )/( m_uvMap[1].x()-m_uvMap[0].x() ); // } // float scale_y=0; // if ( ( m_uvMap[1].y()-m_uvMap[0].y() )==0 ) // { // scale_y=1; // } // else // { // scale_y=( m_points[1].y()-m_points[0].y() )/( m_uvMap[1].y()-m_uvMap[0].y() ); // } // calcAddVertex =LDPoint( uv.x()*scale_x,uv.y()*scale_y ) ; // } else if (m_points.size() >= 2) { LDPoint s0 = m_uvMap[0]; LDPoint s1 = m_uvMap[1]; LDPoint s2 = m_uvMap.Last(); LDPoint t0 = m_points[0]; LDPoint t1 = m_points[1]; calcAddVertex = math.TriangleUtil.getSimilarityTrianglePoint(s0, s1, s2, t0, t1); } return(calcAddVertex); }
//追加。UV経由での追加しかできない。Positionは自動で計算される public void addUv(LDPoint uv, bool clamp = true) { if (clamp) { //0-1区間の縛りに引っかかる処理が多いので、デフォルトでは自動で直す uv = LDMathUtil.clamp(uv, new LDPoint(0, 0), new LDPoint(1, 1)); } else { common.LD_ASSERT_OUT_OF_RANGE(uv.x(), 0, 1); common.LD_ASSERT_OUT_OF_RANGE(uv.y(), 0, 1); } m_uvMap.Add(uv); //頂点の計算 m_points.Add(getCalcAddVertex(uv)); }
public void setClockWise(LDPointList form, ClockWise clockWise) { Debug.Assert(form.length() > m_index1); Debug.Assert(form.length() > m_index2); Debug.Assert(form.length() > m_index3); LDPoint v0 = form.at(m_index1); LDPoint v1 = form.at(m_index2); LDPoint v2 = form.at(m_index3); //行列式で時計回りか判定 //行列式の計算。 QMatrix3x3にはないので手動で作成。 double[,] m = new double[3, 3] { { v0.x(), v0.y(), 1 }, { v1.x(), v1.y(), 1 }, { v2.x(), v2.y(), 1 } }; double determinant = m[0, 0] * m[1, 1] * m[2, 2] + m[0, 1] * m[1, 2] * m[2, 0] + m[0, 2] * m[1, 0] * m[2, 1] - m[0, 2] * m[1, 1] * m[2, 0] - m[0, 0] * m[1, 2] * m[2, 1] - m[0, 1] * m[1, 0] * m[2, 2]; ClockWise current; if (determinant < 0) //CW { current = ClockWise.CW; } else //CCWまたは3点が一直線上など { current = ClockWise.CCW; } if (clockWise != current) //設定した順番と異なる場合 Indexを入れ替える { var p = m_index1; m_index1 = m_index2; m_index2 = p; } }
// 三角形を与えてその外接円を求める public static LDCircle getCircumscribedCirclesOfTriangle(LDPointList form, LDTriangle t) { // 三角形の各頂点座標を (x1, y1), (x2, y2), (x3, y3) とし、 // その外接円の中心座標を (x, y) とすると、 // (x - x1) * (x - x1) + (y - y1) * (y - y1) // = (x - x2) * (x - x2) + (y - y2) * (y - y2) // = (x - x3) * (x - x3) + (y - y3) * (y - y3) // より、以下の式が成り立つ // // x = { (y3 - y1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) // + (y1 - y2) * (x3 * x3 - x1 * x1 + y3 * y3 - y1 * y1)} / c // // y = { (x1 - x3) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) // + (x2 - x1) * (x3 * x3 - x1 * x1 + y3 * y3 - y1 * y1)} / c // // ただし、 // c = 2 * {(x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)} LDPoint p1 = t.getPoint1(form); LDPoint p2 = t.getPoint2(form); LDPoint p3 = t.getPoint3(form); float x1 = (float)p1.x(); float y1 = (float)p1.y(); float x2 = (float)p2.x(); float y2 = (float)p2.y(); float x3 = (float)p3.x(); float y3 = (float)p3.y(); float c = 2.0f * ((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)); float x = ((y3 - y1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) + (y1 - y2) * (x3 * x3 - x1 * x1 + y3 * y3 - y1 * y1)) / c; float y = ((x1 - x3) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) + (x2 - x1) * (x3 * x3 - x1 * x1 + y3 * y3 - y1 * y1)) / c; LDPoint center = new LDPoint(x, y); // 外接円の半径 r は、半径から三角形の任意の頂点までの距離に等しい double r = math.PointUtil.distance(center, p1); return(new LDCircle(center, (float)r)); }
//Gridの内分率からQuadのローカルな内分率を取得する public LDPoint getLocalPoint(LDPoint t) { double tx = t.x(); double ty = t.y(); LDPoint localT = new LDPoint(); if (tx == 0) { localT.setX(0); } else if (tx == 1) { localT.setX(1); } else { double scaled = tx * getColumn(); //小数部を求める localT.setX((float)scaled - (int)Math.Truncate(scaled)); } if (ty == 0) { localT.setY(0); } else if (ty == 1) { localT.setY(1); } else { double scaled = ty * getRow(); //小数部を求める localT.setY((float)scaled - (int)Math.Truncate(scaled)); } return(localT); }
// LDPoint getMappingFrom( int row,int col, LDPoint map ); public LDPoint getMapedQuadIndex(LDPoint map) { //TODO 最適化可能 for (int row = 0; row < getRow(); ++row) { for (int col = 0; col < getColumn(); ++col) { var quad = getQuadTransform(row, col); if (quad.contains(map)) { return(new LDPoint(col, row)); } } } //範囲外を検索する。 //TODO 保険として範囲が広すぎるときはAssert。キャンバスのサイズでどうにか最大値を求めるべき //TODO あまりに無駄が多い var extended = createExtendedGrid(); LDPoint pt = extended.getMapedQuadIndex(map); return(new LDPoint(pt.x() - 1, pt.y() - 1)); }
//円に外接する正三角形を求める public LDPolygon getCircumscribedTriangle() { float x = center.x(); float y = center.y(); // 重心は、円の中心に等しい // 一辺の長さは 2√3・r float x1 = (float)(x - Math.Sqrt(3) * radius); float y1 = (float)(y - radius); LDPoint p1 = new LDPoint(x1, y1); float x2 = (float)(x + Math.Sqrt(3) * radius); float y2 = (float)(y - radius); LDPoint p2 = new LDPoint(x2, y2); float x3 = (float)x; float y3 = (float)(y + 2 * radius); LDPoint p3 = new LDPoint(x3, y3); return(new LDPolygon(new List <LDPoint> { p1, p2, p3 })); }
//平面上の点を変換した結果を返す。pは基本0..1の範囲 /// <summary> /// TODO:LDPoint注意 /// </summary> /// <param name="t"></param> /// <param name="clip"></param> /// <returns></returns> public LDPoint transform(LDPoint t, bool clip = false) { if (getColumn() == 0 && getRow() == 0) { //メッシュがない場合はそのままの値を返す return(t); } double tx = t.x(); double ty = t.y(); if (clip) { //Grid内にClipする。QuadをClipして変換するのではない tx = LDMathUtil.clamp(tx, 0.0, 1.0); ty = LDMathUtil.clamp(ty, 0.0, 1.0); } //Gridから対象のQuadを見つける LDPoint index = getQuadIndex(new LDPoint((float)tx, (float)ty)); int col = (int)index.x(); int row = (int)index.y(); LDPoint local = getLocalPoint(new LDPoint((float)tx, (float)ty)); if (isOutside(row, col)) { LDQuadTransform quad = createOutsideQuadTransform(row, col); return(quad.transform(new LDPoint((float)tx, (float)ty))); } else { LDQuadTransform quad = getQuadTransform(row, col); return(quad.transform(local)); } }
public void transformTest() { { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(30, 30)); LDPoint src=new LDPoint(0.5f, 0.25f); LDPoint dst=new LDPoint(); dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 20.0); TestUtil.COMPARE(dst.y(), 15.0); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(20, 10), new LDPoint(100, 100), new LDPoint(10, 20)); LDPoint src=new LDPoint(0.9f, 0.9f); LDPoint dst=new LDPoint(); dst = quad.transform(src); // TestUtil.COMPARE(dst.x(),83.8); // TestUtil.COMPARE(dst.y(),83.8); TestUtil.LDFUZZY_COMPARE(dst.x(), 83.8, 0.0000001); TestUtil.LDFUZZY_COMPARE(dst.y(), 83.8, 0.0000001); // TestUtil.LDFUZZY_COMPARE(dst.x(),83,0.001); // TestUtil.LDFUZZY_COMPARE(dst.y(),83,0.001); } }
public void inverseTransformTest() { { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(30, 30)); LDPoint src=new LDPoint(20, 15); LDPoint dst=new LDPoint(); dst = quad.inverseTransform(src); TestUtil.COMPARE(dst.x(), 0.5); TestUtil.COMPARE(dst.y(), 0.25); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10), new LDPoint(20, 10), new LDPoint(100, 100), new LDPoint(10, 20)); LDPoint src=new LDPoint(83.8f, 83.8f); LDPoint dst; dst = quad.inverseTransform(src); // TestUtil.COMPARE(dst.x(),0.9); // TestUtil.COMPARE(dst.y(),0.9); TestUtil.LDFUZZY_COMPARE(dst.x(), 0.9, 0.0000001); TestUtil.LDFUZZY_COMPARE(dst.y(), 0.9, 0.0000001); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10), new LDPoint(30, 30)); LDPoint src=new LDPoint(20, 25); LDPoint dst; dst = quad.inverseTransform(src); TestUtil.COMPARE(dst.x(), 0.5); TestUtil.COMPARE(dst.y(), 0.75); } { //(0,0),(100,100)を90度回転 LDQuadTransform quad=new LDQuadTransform( new LDPoint(100, 0), new LDPoint(100, 100), new LDPoint(0, 100), new LDPoint(0, 0) ); LDPoint src=new LDPoint(75, 50); LDPoint dst; dst = quad.inverseTransform(src); TestUtil.COMPARE(dst.x(), 0.5); TestUtil.COMPARE(dst.y(), 0.25); } { //大きめの数字 LDQuadTransform quad=new LDQuadTransform(new LDPoint(1024, 1024), new LDPoint(3500, 3500)); LDPoint src=new LDPoint(2000, 2000); LDPoint dst; dst = quad.inverseTransform(src); TestUtil.LDFUZZY_COMPARE(dst.x(), 0.394184, 0.00001); TestUtil.LDFUZZY_COMPARE(dst.y(), 0.394184, 0.00001); } { //斜め LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(20, 20),new LDPoint(20, 30),new LDPoint(10, 20)); LDPoint src=new LDPoint(15, 20); LDPoint dst; dst = quad.inverseTransform(src); TestUtil.COMPARE(dst.x(), 0.5); TestUtil.COMPARE(dst.y(), 0.5); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10.12345f, 10.12321f),new LDPoint(20.1102f, 20.034f),new LDPoint(20.11111f, 30.22222f), new LDPoint(10.232697f, 20.00008f)); LDPoint src=new LDPoint(15.8731f, 20.5396f); LDPoint dst; LDPoint rest; dst = quad.inverseTransform(src); rest = quad.transform(dst); TestUtil.LDFUZZY_COMPARE(src.x(), rest.x(), 0.0000001); TestUtil.LDFUZZY_COMPARE(src.y(), rest.y(), 0.0000001); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(1023.12345f, 1041.12321f),new LDPoint(2075.1102, 2032.034),new LDPoint(2034.11111, 3061.22222),new LDPoint(1023.232697, 2088.00008)); LDPoint src=new LDPoint(1515.8731, 2072.5396); LDPoint dst; LDPoint rest; dst = quad.inverseTransform(src); rest = quad.transform(dst); TestUtil.LDFUZZY_COMPARE(src.x(), rest.x(), 0.0000001); TestUtil.LDFUZZY_COMPARE(src.y(), rest.y(), 0.0000001); } }
public void setOrigin(LDPoint value) { originX = value.x(); originY = value.y(); }
public LDRect translated(LDPoint p) { return(new LDRect(xp + p.x(), yp + p.y(), w, h)); }
//平面上の点を変換した結果を返す。pは基本0..1の範囲 /// <summary> /// TODO:LDPoint注意 /// </summary> /// <param name="t"></param> /// <param name="clip"></param> /// <returns></returns> public LDPoint transform(LDPoint t, bool clip = false) { if (getColumn() == 0 && getRow() == 0) { //メッシュがない場合はそのままの値を返す return t; } double tx = t.x(); double ty = t.y(); if (clip) { //Grid内にClipする。QuadをClipして変換するのではない tx = LDMathUtil.clamp(tx, 0.0, 1.0); ty = LDMathUtil.clamp(ty, 0.0, 1.0); } //Gridから対象のQuadを見つける LDPoint index = getQuadIndex(new LDPoint((float)tx, (float)ty)); int col = (int)index.x(); int row = (int)index.y(); LDPoint local = getLocalPoint(new LDPoint((float)tx, (float)ty)); if (isOutside(row, col)) { LDQuadTransform quad = createOutsideQuadTransform(row, col); return quad.transform(new LDPoint((float)tx, (float)ty)); } else { LDQuadTransform quad = getQuadTransform(row, col); return quad.transform(local); } }
public void moveBottomLeft(LDPoint p) { moveLeft(p.x()); moveBottom(p.y()); }
public void moveCenter(LDPoint p) { xp = p.x() - w / 2; yp = p.y() - h / 2; }
public void moveTopRight(LDPoint p) { moveRight(p.x()); moveTop(p.y()); }
/// <summary> /// TODO: LDPoint注意 /// </summary> /// <param name="pt"></param> /// <param name="clip"></param> /// <returns></returns> public LDPoint inverseTransform(LDPoint pt, bool clip = false) { if (getColumn() == 0 && getRow() == 0) { //メッシュがない場合はそのままの値を返す return pt; } double x = pt.x(); double y = pt.y(); //Gridからマッピング先のQuadを見つける LDPoint index = getMapedQuadIndex(new LDPoint((float)x, (float)y)); int col = (int)index.x(); int row = (int)index.y(); if (clip) { //Grid内にClipする。QuadをClipして変換するのではない col = LDMathUtil.clamp(col, 0, getColumn()); row = LDMathUtil.clamp(row, 0, getRow()); } LDPoint local = new LDPoint(); if (isOutside(row, col)) { LDQuadTransform quad = createOutsideQuadTransform(row, col); return quad.inverseTransform(pt, clip); //TODO:到達しない場所あります local = quad.inverseTransform(pt, clip); LDPoint _internal=new LDPoint(); _internal.setX((col + 1) * (1.0f / (getColumn() + 2)) + local.x() / (getColumn() + 2)); _internal.setY((row + 1) * (1.0f / (getRow() + 2)) + local.y() / (getRow() + 2)); LDQuadTransform tmp = new LDQuadTransform(new LDPoint(-1, -1), new LDPoint(getColumn() + 1, getRow() + 1)); return tmp.transform(_internal); } else { LDQuadTransform quad = getQuadTransform(row, col); local = quad.inverseTransform(pt, clip); LDPoint _internal = new LDPoint(); _internal.setX(col * (1.0f / getColumn()) + local.x() / getColumn()); _internal.setY(row * (1.0f / getRow()) + local.y() / getRow()); return _internal; } }
public LDGridTransform(LDPoint topLeft, LDPoint bottomRight, int row = 1, int col = 1) : this(topLeft.x(), topLeft.y(), bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y(), row, col) { }
public LDRect translated(LDPoint p) { return new LDRect(xp + p.x(), yp + p.y(), w, h); }
public void translate(LDPoint p) { this.xp += p.x(); this.yp += p.y(); }
public void setTopRight(LDPoint p) { setLeft(p.x()); setBottom(p.y()); }
public void moveTo(LDPoint p) { this.xp = p.x(); this.yp = p.y(); }
private LDPoint getCalcAddVertex(LDPoint uv) { LDPoint calcAddVertex = new LDPoint(-1, -1); //とりあえず -1,-1で初期化 if (m_points.size() == 0) //最初の頂点がなければuvと同じ座標位置にformをする { calcAddVertex = new LDPoint(0, 0); } else if (m_points.size() == 1) //頂点数が一つだけならばその座標を原点としてuvと同じ比率の座標をformにする { LDPoint p0 = m_points.at(0); calcAddVertex = new LDPoint(p0.x() + uv.x(), p0.y() + uv.y()); } // else if ( m_points.size()==2 )// NOTE 計算あまり検証していない // { // //uvと頂点の縮尺を計算 // float scale_x=0; // if ( ( m_uvMap[1].x()-m_uvMap[0].x() )==0 ) // { // scale_x=1; // } // else // { // scale_x=( m_points[1].x()-m_points[0].x() )/( m_uvMap[1].x()-m_uvMap[0].x() ); // } // float scale_y=0; // if ( ( m_uvMap[1].y()-m_uvMap[0].y() )==0 ) // { // scale_y=1; // } // else // { // scale_y=( m_points[1].y()-m_points[0].y() )/( m_uvMap[1].y()-m_uvMap[0].y() ); // } // calcAddVertex =LDPoint( uv.x()*scale_x,uv.y()*scale_y ) ; // } else if (m_points.size() >= 2) { LDPoint s0 = m_uvMap[0]; LDPoint s1 = m_uvMap[1]; LDPoint s2 = m_uvMap.Last(); LDPoint t0 = m_points[0]; LDPoint t1 = m_points[1]; calcAddVertex = math.TriangleUtil.getSimilarityTrianglePoint(s0, s1, s2, t0, t1); } return calcAddVertex; }
public LDPoint transform(LDPoint p) { float rx = p.x() * (float)Math.Cos(rotate) - p.y() * (float)Math.Sin(rotate); float ry = p.x() * (float)Math.Sin(rotate) + p.y() * (float)Math.Cos(rotate); float x = rx * scale + originX; float y = ry * scale + originY; return new LDPoint(x, y); }
public void moveTopLeft(LDPoint p) { moveLeft(p.x()); moveTop(p.y()); }
public void moveBottomRight(LDPoint p) { moveRight(p.x()); moveBottom(p.y()); }
//Gridの内分率からQuadのローカルな内分率を取得する public LDPoint getLocalPoint(LDPoint t) { double tx = t.x(); double ty = t.y(); LDPoint localT = new LDPoint(); if (tx == 0) { localT.setX(0); } else if (tx == 1) { localT.setX(1); } else { double scaled = tx * getColumn(); //小数部を求める localT.setX((float)scaled - (int)Math.Truncate(scaled)); } if (ty == 0) { localT.setY(0); } else if (ty == 1) { localT.setY(1); } else { double scaled = ty * getRow(); //小数部を求める localT.setY((float)scaled - (int)Math.Truncate(scaled)); } return localT; }
public LDVector2(LDPoint point) { this.xp = point.x(); this.yp = point.y(); }
public void inverseTransformTest() { { LDGridTransform grid = new LDGridTransform(20, 20, 40, 40, 2, 2); LDPoint src = new LDPoint(30, 30); LDPoint dst = new LDPoint(); dst = grid.inverseTransform(src); TestUtil.COMPARE(dst.x(), 0.25); TestUtil.COMPARE(dst.y(), 0.25); } { LDGridTransform grid = new LDGridTransform(20, 20, 40, 40, 2, 2); LDPointList src = new LDPointList(); src.add(new LDPoint(30, 30)).add(new LDPoint(50, 50)); LDPointList dst; dst = grid.inverseTransform(src); TestUtil.COMPARE(dst[0], new LDPoint(0.25f, 0.25f)); TestUtil.COMPARE(dst[1], new LDPoint(0.75f, 0.75f)); } /* { LDGridTransform grid = new LDGridTransform(20, 20, 40, 40, 2, 2); LDGridTransform src = new LDGridTransform(24, 24, 52 - 24, 52 - 24, 2, 2); LDGridTransform dst = src; var points = grid.inverseTransform(src.toForm()); dst.setForm(points); LDFUZZY_COMPARE(dst.getPoint(0, 0).x(), 0.1f, 0.0000001f); LDFUZZY_COMPARE(dst.getPoint(2, 2).x(), 0.8f, 0.0000001f); LDFUZZY_COMPARE(dst.getPoint(2, 0).x(), 0.1f, 0.0000001f); LDFUZZY_COMPARE(dst.getPoint(2, 0).y(), 0.8f, 0.0000001f); } */ { LDGridTransform grid = new LDGridTransform(20.53125f, 20.62423f, 40.614312f, 40.94645f, 2, 2); LDGridTransform src = new LDGridTransform(24.0134623f, 24.9143f, 52 - 24.090023f, 52 - 24.00001f, 2, 2); LDGridTransform dst = new LDGridTransform(src); var points = grid.inverseTransform(src.toForm()); var rest = grid.transform(points); dst.setForm(points); TestUtil.VERIFY(LDMathUtil.fuzzyCompare(rest, src.toForm(), 0.0000001f)); } { LDGridTransform grid=new LDGridTransform(2530.53125f, 2540.62423f, 4015.614312f, 4026.94645f, 2, 2); LDGridTransform src=new LDGridTransform(2594.0134623f, 2594.9143f, 5274 - 2594.090023f, 5276 - 2594.00001f, 2, 2); LDGridTransform dst = new LDGridTransform( src); var points = grid.inverseTransform(src.toForm()); var rest = grid.transform(points); dst.setForm(points); TestUtil.VERIFY(LDMathUtil.fuzzyCompare(rest, src.toForm(), 0.0000001f)); } { LDGridTransform grid=new LDGridTransform( new LDPoint(20.53125f, 20.62423f) , new LDPoint(40.53125f, 20.62423f) , new LDPoint(45.53125f, 45.62423f) , new LDPoint(20.614312f, 40.94645f), 2, 2); LDGridTransform src=new LDGridTransform(34.0134623f, 24.9143f, 52 - 24.090023f, 52 - 24.00001f, 8, 8); LDGridTransform dst = new LDGridTransform(src); var points = grid.inverseTransform(src.toForm()); var rest = grid.transform(points); dst.setForm(points); TestUtil.VERIFY(LDMathUtil.fuzzyCompare(rest, src.toForm(), 0.0000001f)); } { LDGridTransform grid=new LDGridTransform( new LDPoint(2012.53125f, 2051.62423f) , new LDPoint(4097.53125f, 2033.62423f) , new LDPoint(4575.53125f, 4566.62423f) , new LDPoint(2062.614312f, 4000.94645f), 2, 2); LDGridTransform src=new LDGridTransform(3444.0134623f, 2442.9143f, 5242 - 2412.090023f, 5211 - 2467.00001f, 8, 8); LDGridTransform dst = new LDGridTransform(src); var points = grid.inverseTransform(src.toForm()); var rest = grid.transform(points); dst.setForm(points); TestUtil.VERIFY(LDMathUtil.fuzzyCompare(rest, src.toForm(), 0.0000001f)); } }
public LDPoint getQuadIndex(LDPoint t) { double tx = t.x(); double ty = t.y(); // Debug.Assert( tx>=0 ); // Debug.Assert( tx<=1 ); // Debug.Assert( ty>=0 ); // Debug.Assert( ty<=1 ); int row, col; if (tx == 1) { col = getColumn() - 1; } else { col = (int)Math.Truncate(tx * getColumn()); } if (ty == 1) { row = getRow() - 1; } else { row = (int)Math.Truncate(ty * getRow()); } return new LDPoint(col, row); }
public void setBottomRight(LDPoint p) { setRight(p.x()); setTop(p.y()); }
public static LDPoint clamp(LDPoint value, LDPoint min, LDPoint max) { return(new LDPoint( clamp(value.x(), min.x(), max.x()), clamp(value.y(), min.y(), max.y()))); }
public void setTopLeft(LDPoint p) { setLeft(p.x()); setTop(p.y()); }
public void extendedTransformTest() { //範囲外補間 { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(30, 30)); LDPoint src=new LDPoint(-1, -1); LDPoint dst; dst = quad.transform(src); TestUtil.COMPARE(dst.x(), -10.0); TestUtil.COMPARE(dst.y(), -10.0); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(30, 30)); LDPoint src=new LDPoint(-1, -1); LDPoint dst; dst = quad.transform(src, true);//範囲内にクリッピングする TestUtil.COMPARE(dst.x(), 10.0); TestUtil.COMPARE(dst.y(), 10.0); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(30, 30)); LDPoint src=new LDPoint(2, 2); LDPoint dst; dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 50.0); TestUtil.COMPARE(dst.y(), 50.0); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(30, 30)); LDPoint src= new LDPoint(40, 40); LDPoint dst; dst = quad.inverseTransform(src); TestUtil.COMPARE(dst.x(), 1.5); TestUtil.COMPARE(dst.y(), 1.5); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10),new LDPoint(30, 30)); LDPoint src=new LDPoint(40, 40); LDPoint dst; dst = quad.inverseTransform(src, true); TestUtil.COMPARE(dst.x(), 1.0); TestUtil.COMPARE(dst.y(), 1.0); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10.12345, 10.12321), new LDPoint(20.1102, 20.034), new LDPoint(20.11111, 30.22222), new LDPoint(10.232697, 20.00008)); LDPoint src=new LDPoint(45.8731, 60.5396); LDPoint dst; LDPoint rest; dst = quad.inverseTransform(src); rest = quad.transform(dst); TestUtil.LDFUZZY_COMPARE(src.x(), rest.x(), 0.0000001); TestUtil.LDFUZZY_COMPARE(src.y(), rest.y(), 0.0000001); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(1023.12345, 1041.12321), new LDPoint(2075.1102, 2032.034), new LDPoint(2034.11111, 3061.22222), new LDPoint(1023.232697, 2088.00008)); LDPoint src=new LDPoint(11515.8731, 62072.5396); LDPoint dst; LDPoint rest; dst = quad.inverseTransform(src); rest = quad.transform(dst); TestUtil.LDFUZZY_COMPARE(src.x(), rest.x(), 0.0000001); TestUtil.LDFUZZY_COMPARE(src.y(), rest.y(), 0.0000001); } { LDQuadTransform quad=new LDQuadTransform(new LDPoint(1023.12345, 1041.12321), new LDPoint(2075.1102, 2032.034), new LDPoint(2034.11111, 3061.22222), new LDPoint(1023.232697, 2088.00008)); LDPoint src=new LDPoint(5.8731, 72.5396); LDPoint dst; LDPoint rest; dst = quad.inverseTransform(src); rest = quad.transform(dst); TestUtil.LDFUZZY_COMPARE(src.x(), rest.x(), 0.0000001); TestUtil.LDFUZZY_COMPARE(src.y(), rest.y(), 0.0000001); } }