public void simpleTransformTest() { { LDSimpleAffineTransform t=new LDSimpleAffineTransform(); t.setOrigin(new LDPoint(100, 100)); t.setRotateDeg(90); LDPoint src=new LDPoint(1, 0); LDPoint dst; dst = t.transform(src); TestUtil.COMPARE(dst.x(), (double)100); TestUtil.COMPARE(dst.y(), (double)100 + 1); } { LDSimpleAffineTransform t=new LDSimpleAffineTransform(); t.setOrigin(new LDPoint(100, 100)); t.setRotateDeg(90); t.setScale(2); LDPoint src=new LDPoint(5, 5); LDPoint dst; dst = t.transform(src); TestUtil.COMPARE(dst.x(), 90.0); TestUtil.COMPARE(dst.y(), 110.0); } }
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(); }
public static LDPoint lerp2D(LDPoint from1, LDPoint to1, double t1, LDPoint from2, LDPoint to2, double t2) { LDPoint tmp1 = (1 - (float)t1) * from1 + (float)t1 * to1; LDPoint tmp2 = (1 - (float)t1) * from2 + (float)t1 * to2; return((1 - (float)t2) * tmp1 + (float)t2 * tmp2); }
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 bool isHit(LDPoint pt) { LDPolygon polygon = m_triangles.getOutlinePolygon(m_points); //第二引数のFillRuleはQPainterPathのリファレンスがわかりやすい return(polygon.containsPoint(pt, FillRule.WindingFill)); }
public void simpleTransformTest() { { LDSimpleAffineTransform t = new LDSimpleAffineTransform(); t.setOrigin(new LDPoint(100, 100)); t.setRotateDeg(90); LDPoint src = new LDPoint(1, 0); LDPoint dst; dst = t.transform(src); TestUtil.COMPARE(dst.x(), (double)100); TestUtil.COMPARE(dst.y(), (double)100 + 1); } { LDSimpleAffineTransform t = new LDSimpleAffineTransform(); t.setOrigin(new LDPoint(100, 100)); t.setRotateDeg(90); t.setScale(2); LDPoint src = new LDPoint(5, 5); LDPoint dst; dst = t.transform(src); TestUtil.COMPARE(dst.x(), 90.0); TestUtil.COMPARE(dst.y(), 110.0); } }
public LDRect(LDPoint topleft, LDSize size) { this.xp = topleft.x(); this.yp = topleft.y(); this.w = size.width(); this.h = size.height(); }
/// <summary> /// out Upoint 未実装 /// </summary> /// <param name="l"></param> /// <param name="point"></param> /// <returns></returns> public IntersectType intersect(LDLine l, out LDPoint point) { 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); }
//時計回りに4点 public LDQuadTransform(LDPoint topLeft, LDPoint topRight, LDPoint bottomRight, LDPoint bottomLeft) { m_topLeft = topLeft; m_bottomRight = bottomRight; m_topRight = topRight; m_bottomLeft = bottomLeft; }
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 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 double crossProductValue(LDPoint pa, LDPoint pb) { // pa と pb の外積の z 成分を求める double n = pa.x() * pb.y() - pa.y() * pb.x(); return(n); }
/// <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 LDPoint getNormalizedPoint(int row, int col) { LDPoint p = new LDPoint(); p.setX(1.0f / getColumn() * row); p.setY(1.0f / getRow() * col); return(p); }
public void insertUv(int index, LDPoint uv) { m_uvMap.Insert(index, uv); m_points.Insert(index, getCalcAddVertex(uv)); //form.insert( index,p ); updateLinesForPointInsert(index); }
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 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 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 void setAngle(float angle) { if (this.isNull()) { return; } this.length(); this.pt2 = new LDPoint((float)(this.pt1.x() + this.length() * Math.Cos(angle)), (float)(this.pt1.y() + this.length() * Math.Sin(angle))); }
//矩形に含まれるかどうかの軽量な簡易当たり判定 public bool isPreHit(LDPoint pt, float hitRange = 0) { LDRect rect = getBounds(); //上下左右を拡張 rect.adjust(-hitRange, -hitRange, hitRange, hitRange); return(rect.contains(pt)); }
public void setPoint(int row, int col, LDPoint pt) { Debug.Assert(m_gridPoints.Count != 0); common.LD_ASSERT_OUT_OF_INDEX(m_gridPoints, row); common.LD_ASSERT_OUT_OF_INDEX(m_gridPoints[0], col); m_gridPoints[row][col] = pt; clearBoundsCache(); }
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 void setLength(float len) { if (this.isNull()) { return; } LDLine v = this.unitVector(); this.pt2 = new LDPoint(this.pt1.x() + v.dx() * len, this.pt1.y() + v.dy() * len); }
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 bool isHitOutline(LDPoint pt, float hitRange) { if (!isPreHit(pt, hitRange)) { return(false); } LDIndexLineList outline = getIndexOutline(); return(outline.isHit(toForm(), pt, hitRange)); }
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 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()); }
public bool isHit(LDPointList form, LDPoint p, float hitRange) { for (int i = 0; i < this.size(); i++) { if (this.at(i).isHit(form, p, hitRange)) { return(true); } } return(false); }
/* * public void serializeTest() * { * string name = "gridMesh"; * LDGridTransform src = new LDGridTransform(0, 0, 100, 100, 2, 2)); * * //シリアライズ * SerializeHelper.writeBoostXml(name, src); * * //デシリアライズ * var dst = SerializeHelper.readBoostXml<LDGridTransform>(name); * * TestUtil.VERIFY(dst->getGridPoints() == src->getGridPoints()); * } */ public void simpleTransformTest() { LDGridTransform grid = new LDGridTransform(20, 20, 40, 40, 1, 1); { LDPoint src = new LDPoint(0.5f, 0.5f); LDPoint dst; dst = grid.transform(src); TestUtil.COMPARE(dst.x(), 40.0); TestUtil.COMPARE(dst.y(), 40.0); } { LDPointList src = new LDPointList(); src.add(new LDPoint(0.25f, 0.25f)).add(new LDPoint(0.75f, 0.75f)); LDPointList dst; dst = grid.transform(src); TestUtil.VERIFY(dst.length() == 2); TestUtil.COMPARE(dst[0], new LDPoint(30.0f, 30)); TestUtil.COMPARE(dst[1], new LDPoint(50.0f, 50)); } { LDGridTransform src = new LDGridTransform(0.5f, 0.5f, 0.5f, 0.5f, 1, 1); LDGridTransform dst = new LDGridTransform(); dst = grid.transform(src); TestUtil.COMPARE(dst.getPoint(0, 0), new LDPoint(40, 40)); TestUtil.COMPARE(dst.getPoint(0, 1), new LDPoint(60, 40)); TestUtil.COMPARE(dst.getPoint(1, 1), new LDPoint(60, 60)); TestUtil.COMPARE(dst.getPoint(1, 0), new LDPoint(40, 60)); } { LDAffineTransform src = new LDAffineTransform(); src.translate(0.5f, 0.5f); src.rotate(30); src.scale(2, 2); LDAffineTransform dst = new LDAffineTransform(); dst = grid.transform(src); TestUtil.COMPARE(dst.getTranslate(), new LDPoint(40, 40)); } }
/// <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); } }
//2次ベジエ曲線上の点を求める。t=0:開始点 t=1:終了点 public static LDPoint quadraticBezierPoint( LDPoint start, LDPoint control, LDPoint end, float t) { float t1 = (1 - t) * (1 - t); float t2 = 2 * t * (1 - t); float t3 = t * t; return(t1 * start + t2 * control + t3 * end); }
//2次ベジエ曲線上の点を求める。t=0:開始点 t=1:終了点 public static LDPoint quadraticBezierPoint( LDPoint start, LDPoint control, LDPoint end,float t) { float t1 = (1 - t) * (1 - t); float t2 = 2 * t * (1 - t); float t3 = t * t; return t1* start + t2* control + t3* end; }
public void inverseTransformTest() { { LDSimpleAffineTransform t=new LDSimpleAffineTransform(); t.setOrigin(new LDPoint(100, 100)); t.setRotateDeg(90); LDPoint src=new LDPoint(100, 101); LDPoint dst; dst = t.inverseTransform(src); TestUtil.COMPARE(dst.x(), (double)1); TestUtil.LDFUZZY_COMPARE(dst.y(), (double)0, 0.0001); } }
//3次ベジエ曲線上の点を求める。t=0:開始点 t=1:終了点 public static LDPoint cubicBezierPoint( LDPoint start, LDPoint control1, LDPoint control2, LDPoint end, float t) { float t1 = (1 - t) * (1 - t) * (1 - t); float t2 = 3 * t * (1 - t) * (1 - t); float t3 = 3 * t * t * (1 - t); float t4 = t * t * t; return t1 * start + t2 * control1 + t3 * control2 + t4 * end; }
//時計回りに4点 public LDGridTransform(LDPoint topLeft, LDPoint topRight, LDPoint bottomRight, LDPoint bottomLeft, int row = 1, int col = 1) { m_originRect = math.PointUtil.getBoundingRect(new LDPointList { topLeft, topRight, bottomLeft, bottomRight }); LDQuadTransform quad = new LDQuadTransform(topLeft, topRight, bottomRight, bottomLeft); for (int i = 0; i < row + 1; ++i) { m_gridPoints.Add(new List<LDPoint>()); for (int j = 0; j < col + 1; ++j) { m_gridPoints[i].Add(quad.transform((float)j / col, (float)i / row)); } } clearBoundsCache(); }
//追加。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)); }
//エルミート曲線上の点を求める。t=0:開始点 t=1:終了点 static LDPoint cubicHermitePoint( LDPoint start, LDPoint startVec, LDPoint end, LDPoint endVec, float t) { // P(t) = at3 + bt2 + ct + d // a = 2(P0 - P1) + m0 + m1 // b = -3(P0 - P1) - 2m0 - m1 // c = m0 // d = P0 float t2 = t * t; float t3 = t * t * t; LDPoint a = 2 * (start - end) + startVec + endVec; LDPoint b = -3 * (start - end) - 2 * startVec - endVec; return a * t3 + b * t2 + startVec * t + start; }
// 三角形を与えてその外接円を求める 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); }
//円に外接する正三角形を求める 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}); }
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 setTopLeft(LDPoint p) { setLeft(p.x()); setTop(p.y()); }
public LDRect translated(LDPoint p) { return new LDRect(xp + p.x(), yp + p.y(), w, h); }
public void moveTopRight(LDPoint p) { moveRight(p.x()); moveTop(p.y()); }
public void setBottomRight(LDPoint p) { setRight(p.x()); setTop(p.y()); }
public float dotProduct(LDPoint p1, LDPoint p2) { return p1.xp * p2.yp + p2.xp + p1.yp; }
public LDPoint(LDPoint p) { this.xp = p.xp; this.yp = p.yp; }
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 void extendedTransformTest() { { //拡張したGridの取得 LDGridTransform src=new LDGridTransform(20, 20, 40, 40, 3, 3); LDGridTransform dst = src.createExtendedGrid(); TestUtil.COMPARE(dst.getRow(), 4); TestUtil.COMPARE(dst.getColumn(), 4); TestUtil.COMPARE(dst.getPoint(0, 0), new LDPoint(-20, -20)); TestUtil.COMPARE(dst.getPoint(0, 1), new LDPoint(10, -20)); TestUtil.COMPARE(dst.getPoint(0, 2), new LDPoint(40, -20)); TestUtil.COMPARE(dst.getPoint(0, 3), new LDPoint(70, -20)); TestUtil.COMPARE(dst.getPoint(0, 4), new LDPoint(100, -20)); TestUtil.COMPARE(dst.getPoint(1, 1), new LDPoint(20, 20)); } { //範囲外 順変換 クリッピング LDGridTransform grid=new LDGridTransform(20, 20, 40, 40, 1, 1); LDPoint src=new LDPoint(-1, -1); LDPoint dst; dst = grid.transform(src, true); TestUtil.COMPARE(dst.x(), 20.0); TestUtil.COMPARE(dst.y(), 20.0); } { //範囲外 順変換 LDGridTransform grid=new LDGridTransform(20, 20, 40, 40, 1, 1); LDPoint src=new LDPoint(-1, -1); LDPoint dst; dst = grid.transform(src); TestUtil.COMPARE(dst.x(), -20.0); TestUtil.COMPARE(dst.y(), -20.0); } { //範囲外 順変換 LDGridTransform grid=new LDGridTransform(20, 20, 40, 40, 1, 1); LDPoint src=new LDPoint(-10, -10); LDPoint dst; dst = grid.transform(src); TestUtil.COMPARE(dst.x(), -380.0); TestUtil.COMPARE(dst.y(), -380.0); } { //範囲外 逆変換 クリッピング LDGridTransform grid=new LDGridTransform(20, 20, 40, 40, 2, 2); LDPoint src=new LDPoint(-20, -20); LDPoint dst; dst = grid.inverseTransform(src, true); TestUtil.COMPARE(dst.x(), 0.0); TestUtil.COMPARE(dst.y(), 0.0); } { //範囲外 逆変換 LDGridTransform grid=new LDGridTransform(20, 20, 40, 40, 2, 2); LDPoint src=new LDPoint(-20, -20); LDPoint dst; dst = grid.inverseTransform(src); TestUtil.COMPARE(dst.x(), -1.0); TestUtil.COMPARE(dst.y(), -1.0); } { 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(3425.0134623f, 2412.9143f, 5252 - 2412.090023f, 5212 - 2451.00001f, 2, 8); LDGridTransform dst = 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(34.0134623f, 24.9143f, 52 - 24.090023f, 52 - 24.00001f, 8, 2); LDGridTransform dst = 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 void serializeTest() { string name = "gridMesh"; LDGridTransform src = new LDGridTransform(0, 0, 100, 100, 2, 2)); //シリアライズ SerializeHelper.writeBoostXml(name, src); //デシリアライズ var dst = SerializeHelper.readBoostXml<LDGridTransform>(name); TestUtil.VERIFY(dst->getGridPoints() == src->getGridPoints()); } */ public void simpleTransformTest() { LDGridTransform grid = new LDGridTransform(20, 20, 40, 40, 1, 1); { LDPoint src = new LDPoint(0.5f, 0.5f); LDPoint dst; dst = grid.transform(src); TestUtil.COMPARE(dst.x(), 40.0); TestUtil.COMPARE(dst.y(), 40.0); } { LDPointList src = new LDPointList(); src.add(new LDPoint(0.25f, 0.25f)).add(new LDPoint(0.75f, 0.75f)); LDPointList dst; dst = grid.transform(src); TestUtil.VERIFY(dst.length() == 2); TestUtil.COMPARE(dst[0], new LDPoint(30.0f, 30)); TestUtil.COMPARE(dst[1], new LDPoint(50.0f, 50)); } { LDGridTransform src = new LDGridTransform(0.5f, 0.5f, 0.5f, 0.5f, 1, 1); LDGridTransform dst = new LDGridTransform(); dst = grid.transform(src); TestUtil.COMPARE(dst.getPoint(0, 0),new LDPoint(40, 40)); TestUtil.COMPARE(dst.getPoint(0, 1),new LDPoint(60, 40)); TestUtil.COMPARE(dst.getPoint(1, 1),new LDPoint(60, 60)); TestUtil.COMPARE(dst.getPoint(1, 0),new LDPoint(40, 60)); } { LDAffineTransform src = new LDAffineTransform(); src.translate(0.5f, 0.5f); src.rotate(30); src.scale(2, 2); LDAffineTransform dst = new LDAffineTransform(); dst = grid.transform(src); TestUtil.COMPARE(dst.getTranslate(), new LDPoint(40, 40)); } }
public void translate(LDPoint p) { this.xp += p.x(); this.yp += p.y(); }
public void rotationTest() { { //(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(0.5, 0.25); LDPoint dst; dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 75.0); TestUtil.COMPARE(dst.y(), 50.0); } { //(0,0),(100,100)を180度回転 LDQuadTransform quad=new LDQuadTransform( new LDPoint(100, 100), new LDPoint(0, 100), new LDPoint(0, 0), new LDPoint(100, 0) ); LDPoint src=new LDPoint(0.5, 0.25); LDPoint dst; dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 50.0); TestUtil.COMPARE(dst.y(), 75.0); } }
public void simpleTransformTest() { LDQuadTransform quad=new LDQuadTransform(new LDPoint(10, 10), new LDPoint(30, 30)); { LDPoint src=new LDPoint(0, 0); LDPoint dst; dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 10.0); TestUtil.COMPARE(dst.y(), 10.0); } { LDPoint src=new LDPoint(1, 1); LDPoint dst; dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 30.0); TestUtil.COMPARE(dst.y(), 30.0); } { LDPoint src=new LDPoint(0.5f, 0.25f); LDPoint dst; dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 20.0f); TestUtil.COMPARE(dst.y(), 15.0f); } { LDPoint src=new LDPoint(0.75f, 0.8f); LDPoint dst; dst = quad.transform(src); TestUtil.COMPARE(dst.x(), 25.0f); TestUtil.COMPARE(dst.y(), 26.0f); } { LDPointList src=new LDPointList(); src.add(new LDPoint(0.25f, 0.4f)).add( new LDPoint(0.75f, 0.8f)); LDPointList dst; dst = quad.transform(src); TestUtil.VERIFY(dst.length() == 2); TestUtil.COMPARE(dst[0],new LDPoint(15.0f, 18.0f)); TestUtil.COMPARE(dst[1],new LDPoint(25, 26)); } // { // LDGridTransform src(0.5,0.5,0.5,0.5,1,1); // LDGridTransform dst; // dst=grid.transform(src); // TestUtil.COMPARE(dst.getPoint(0,0),LDPoint(40,40)); // TestUtil.COMPARE(dst.getPoint(0,1),LDPoint(60,40)); // TestUtil.COMPARE(dst.getPoint(1,1),LDPoint(60,60)); // TestUtil.COMPARE(dst.getPoint(1,0),LDPoint(40,60)); // } // { // LDAffineTransform src; // src.translate(0.5,0.5); // src.rotate(30); // src.scale(2,2); // LDAffineTransform dst; // dst=grid.transform(src); // TestUtil.COMPARE(dst.getTranslate(),LDPoint(40,40)); // } }
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 setTopRight(LDPoint p) { setLeft(p.x()); setBottom(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); } }