Hej,
Potrzebuję się Was poradzić. Piszę dodatek standalone, który wrzuca do Excela pewne dane.
Dodatkową funkcją jest rysowanie polilinii na podstawie wygenerowanego wcześniej łańcucha znaków.
Łańcuch jest w postaci (przykład):
95.0,16.0,195.0,59.0<-30.4
Rozbijając po znaku przecinka "," otrzymujemy długości poszczególnych boków. Przecinek oznajmia nam także, iż kolejny bok do poprzedniego jest rysowany pod kątem prostym. Jeśli tak nie jest (tzn. mamy kąt inny niż prosty), to kąt ten określamy znakiem "<".
Pomierzony kąt jest kątem między wektorami, które odczytałem wcześniej.
Z racji tego, iż dodatek musi działać z poprzednimi "wersjami" łańcuchów, nie mam możliwości modyfikacji zapisywania "schematu" kształtu.
Tutaj są zaprezentowane dwa schematy:
http://gpasko.website.pl/excel.jpg
Żółta strzałka określa kierunek "czytania" łańcucha.
I teraz mając taki łańcuch, potrzebuję narysować w Excelu kształt.
Ograniczają mnie rozmiary komórki, przez co potrzebuję skalować boki, jak również ogranicza mnie "margines" okna excela.
Korzystam z EPPlus do generowania plików, ale to tutaj nie ma znaczenia.
Chodzi mi głównie o algorytm, na razie napisałem sobie coś takiego:
` `` `
private class RodTypeArray
{
public double x;
public double y;
public double width;
public double angle;
}
private void DrawRodShape(string type, int currentRecord, int currentPage, ExcelWorksheet specSheet, int currentRod)
{
int currentRow = 6 + currentRecord + 32 * (currentPage - 1);
int cellMaxWidth = 170;
int cellMaxHeight = 30;
int offsetTop = 0;
int offsetLeft = 0;
List<RodTypeArray> rta = new List<RodTypeArray>();
rodLine rod = new rodLine(type);
for (int i = 0; i < rod.ElementsCount; i++)
{
double angle = rod.ElementAt(i).Angle;
RodTypeArray r = new RodTypeArray();
rodElement e = rod.ElementAt(i);
angle = angle * Math.PI / 180.0;
r.width = e.Length;
r.angle = angle;
rta.Add(r);
}
rta[0].angle = 0;
double _prevAngle = 0.0;
double width = 0.0;
double height = 0.0;
double maxWidth = 0.0;
double maxHeight = 0.0;
for (int i = 0; i < rod.ElementsCount; i++)
{
_prevAngle += rta[i].angle;
rta[i].x = rta[i].width * Math.Cos(_prevAngle);
rta[i].y = rta[i].width * Math.Sin(_prevAngle);
//}
width += rta[i].x;
height += rta[i].y;
maxWidth = Math.Max(Math.Abs(width), maxWidth);
maxHeight = Math.Max(Math.Abs(height), maxHeight);
}
double scaleCorrectionX = 1.0;
double scaleCorrectionY = 1.0;
if (maxWidth > cellMaxWidth)
scaleCorrectionX = cellMaxWidth / maxWidth;
if (maxHeight > cellMaxHeight)
scaleCorrectionY = cellMaxHeight / maxHeight;
int startX = 0;
int startY = 0;
string _test2 = string.Empty;
offsetTop = 1443 * (currentPage - 1) + 223 + (currentRecord - 1) * 51 + 10;
offsetLeft = 117 + Math.Abs(Convert.ToInt32((cellMaxWidth - maxWidth * scaleCorrectionX) / 2));
for (int i = 0; i < rta.Count; i++)
{
startX = (int)(rta[i].x * scaleCorrectionX);
startY = (int)(rta[i].y * scaleCorrectionY);
bool goBack = false;
if (startY < 0)
{
goBack = true;
offsetTop += startY;
}
if (startX < 0)
{
goBack = true;
offsetLeft += startX;
}
startX = Math.Abs(startX);
startY = Math.Abs(startY);
AddLineShape(string.Format("shape_p{0}_{1}_{2}", currentPage, currentRecord, i), offsetTop, offsetLeft, startX, startY, specSheet);
if (!goBack)
{
offsetLeft += startX;
offsetTop += startY;
}
}
}
rodLine to obiekt łańcucha, rodElement to obiekt konkretnego "boku" kształtu.
Niestety nie wszystkie kształty udaje mi się narysować prawidłowo:
http://gpasko.website.pl/excel2.jpg
Chciałbym się poradzić, jak powinienem fachowo podejść do tematu, bo mój kod jest na razie ... no bardzo prymitywny chyba.
Może ktoś mi będzie mógł chociaż trochę pomóc, podpowiedzieć. A może gdzieś w internecie jest jakiś dobry kod do rysowania polilinii na podstawie długości boków i kątów. To by mi mogło pomóc :)
Dzięki!