public static VertexStore TransformToVxs(ref AffineMat aff, VertexStore src, VertexStore outputVxs) { int count = src.Count; VertexCmd cmd; double x, y; for (int i = 0; i < count; ++i) { cmd = src.GetVertex(i, out x, out y); aff.Transform(ref x, ref y); outputVxs.AddVertex(x, y, cmd); } //outputVxs.HasMoreThanOnePart = src.HasMoreThanOnePart; return(outputVxs); }
//-------------------------------------------------------------------- public void init(double x0, double y0, double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double x2, double y2) { m_radii_ok = true; if (rx < 0.0) { rx = -rx; } if (ry < 0.0) { ry = -rx; } // Calculate the middle point between // the current and the final points //------------------------ double dx2 = (x0 - x2) / 2.0; double dy2 = (y0 - y2) / 2.0; double cos_a = Math.Cos(angle); double sin_a = Math.Sin(angle); // Calculate (x1, y1) //------------------------ double x1 = cos_a * dx2 + sin_a * dy2; double y1 = -sin_a * dx2 + cos_a * dy2; // Ensure radii are large enough //------------------------ double prx = rx * rx; double pry = ry * ry; double px1 = x1 * x1; double py1 = y1 * y1; // Check that radii are large enough //------------------------ double radii_check = px1 / prx + py1 / pry; if (radii_check > 1.0) { rx = Math.Sqrt(radii_check) * rx; ry = Math.Sqrt(radii_check) * ry; prx = rx * rx; pry = ry * ry; if (radii_check > 10.0) { m_radii_ok = false; } } // Calculate (cx1, cy1) //------------------------ double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0; double sq = (prx * pry - prx * py1 - pry * px1) / (prx * py1 + pry * px1); double coef = sign * Math.Sqrt((sq < 0) ? 0 : sq); double cx1 = coef * ((rx * y1) / ry); double cy1 = coef * -((ry * x1) / rx); // // Calculate (cx, cy) from (cx1, cy1) //------------------------ double sx2 = (x0 + x2) / 2.0; double sy2 = (y0 + y2) / 2.0; double cx = sx2 + (cos_a * cx1 - sin_a * cy1); double cy = sy2 + (sin_a * cx1 + cos_a * cy1); // Calculate the start_angle (angle1) and the sweep_angle (dangle) //------------------------ double ux = (x1 - cx1) / rx; double uy = (y1 - cy1) / ry; double vx = (-x1 - cx1) / rx; double vy = (-y1 - cy1) / ry; double p, n; // Calculate the angle start //------------------------ n = Math.Sqrt(ux * ux + uy * uy); p = ux; // (1 * ux) + (0 * uy) sign = (uy < 0) ? -1.0 : 1.0; double v = p / n; if (v < -1.0) { v = -1.0; } if (v > 1.0) { v = 1.0; } double start_angle = sign * Math.Acos(v); // Calculate the sweep angle //------------------------ n = Math.Sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy)); p = ux * vx + uy * vy; sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0; v = p / n; if (v < -1.0) { v = -1.0; } if (v > 1.0) { v = 1.0; } double sweep_angle = sign * Math.Acos(v); if (!sweep_flag && sweep_angle > 0) { sweep_angle -= Math.PI * 2.0; } else if (sweep_flag && sweep_angle < 0) { sweep_angle += Math.PI * 2.0; } // We can now build and transform the resulting arc //------------------------ m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle); AffineMat mtx = AffineMat.Iden(); mtx.Rotate(angle); mtx.Translate(cx, cy); //Affine mtx = Affine.New( // AffinePlan.Rotate(angle), // AffinePlan.Translate(cx, cy) // ); for (int i = 2; i < m_arc.m_num_vertices - 2; i += 2) { mtx.Transform(ref m_arc.m_vertices[i], ref m_arc.m_vertices[i + 1]); } // We must make sure that the starting and ending points // exactly coincide with the initial (x0,y0) and (x2,y2) m_arc.m_vertices[0] = x0; m_arc.m_vertices[1] = y0; if (m_arc.m_num_vertices > 2) { m_arc.m_vertices[m_arc.m_num_vertices - 2] = x2; m_arc.m_vertices[m_arc.m_num_vertices - 1] = y2; } }