Консультация № 67332
17.12.2006, 08:25
0.00 руб.
0 1 1
Здравствуйте! Подскажите пожалуйста...уже какой день ищу ошибку. Ниже приведен код программы в C++Builder 6.
По заданию мне надо задать многоугольник и с помощью кнопок производить над ним некоторые действия (перемещения вправо, влево и т.д., вращение по часовой и против а также сжатие и растяжение)
В программе заполняю массив TPoint точек а потом с помощью Polygon отображаю его.
Есть следующие кнопки.
Button1 рисует в скрол баре поля для ввода х и у координат вершин.
Button2 заполняет массив TPoint координатами вершин.
ToolButton7 поворачивает фигуру.
ToolButton2 движет её вправо.

Все едействия должны быть НЕ взаимосвязаны, т.е. если я повращал фигуру, то при нажатии на кнопк "вправо" она должна сдвинутся с места не от места куда я её повернул а из изначального положения, это же для перемещения. Должно потом вращатся из изначального положения.
Проблема в том что у меня вращения получается взаимосвязанным от перемещения, т.е. если я немного подвигал и начинаю вращать он вращает не из начального места а из передвинутого.
Посмотри пожалуйста код.

Заранее большое спасибо!!!


Приложение:
//---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include "Unit1.h"//---------------------------------------------------------------------------#pragma package(smart_init)#pragma resource "*.dfm"#include <math.h>#include <stdio.h>TForm1 *Form1;TEdit **m;TEdit **l;int n;TPoint *p;float f=0;float x=0, y=0, x0=0, y0=0;//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){}//---------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender){try{n=StrToInt(Edit1->Text);m=new TEdit *[n];l=new TEdit *[n];for(int i=0, s=1; i<(n), s<=(n); i++, s++){m[i]=new TEdit(ScrollBox1);m[i]->Parent=ScrollBox1;m[i]->Height=21;m[i]->Width=40;m[i]->Left=110;m[i]->Top=30+30*i;}for(int i=0, s=1; i<(n), s<=(n); i++, s++){l[i]=new TEdit(ScrollBox1);l[i]->Parent=ScrollBox1;l[i]->Height=21;l[i]->Width=40;l[i]->Left=200;l[i]->Top=30+30*i;}}}catch(EConvertError &e){ShowMessage("Неправильный ввод!!! Повторите попытку...");}}void __fastcall TForm1::Button2Click(TObject *Sender){Image1->Canvas->Pen->Width=1;p=new TPoint[n];try{for(int i=0; i<n; i++){p[i].x=StrToFloat(m[i]->Text);p[i].y=StrToFloat(l[i]->Text);}}catch(EConvertError &e){ShowMessage("Неправильный ввод!");return;}catch(EAccessViolation &e){ShowMessage("Ошибка. Обратитесь к разработчику программ!");return;}Image1->Canvas->Polygon(p, n-1);}//---------------------------------------------------------------------------void __fastcall TForm1::ToolButton7Click(TObject *Sender){TPoint *p1;p1=new TPoint[n];try{float x1, y1;if(N10->Checked==true){f-=0.1;for(int i=0; i<n; i++){x1=x+(p[i].x-x)*cos(f)+(p[i].y-y)*sin(f);y1=y-(p[i].x-x)*sin(f)+(p[i].y-y)*cos(f);p1[i].x=x1;p1[i].y=y1;}Image1->Canvas->FillRect(Rect(0, 0, Image1->Width, Image1->Height));Image1->Canvas->Pen->Width=1;Image1->Canvas->Polygon(p1, n-1);}else{f-=0.1;for(int i=0; i<n; i++){x1=x+(p[i].x-0)*cos(f)+(p[i].y-0)*sin(f);y1=y-(p[i].x-0)*sin(f)+(p[i].y-0)*cos(f);p1[i].x=x1;p1[i].y=y1;}Image1->Canvas->FillRect(Rect(0, 0, Image1->Width, Image1->Height));Image1->Canvas->Pen->Width=1;Image1->Canvas->Polygon(p1, n-1);}}catch(EAccessViolation &e){ShowMessage("Для работы с многоугольгиком его надо сначала задать...!");}}//---------------------------------------------------------------------------void __fastcall TForm1::ToolButton2Click(TObject *Sender){TPoint *p2;p2=new TPoint[n];p2=p;try{Image1->Canvas->Pen->Width=1;for(int i=0; i<n; i++){p2[i].x+=5;}Image1->Canvas->FillRect(Rect(0, 0, Image1->Width, Image1->Height));Image1->Canvas->Pen->Width=1;Image1->Canvas->Polygon(p2, n-1);}catch(EAccessViolation &e){ShowMessage("Для работы с многоугольгиком его надо сначала задать...!");}}

Обсуждение

Неизвестный
18.12.2006, 09:53
общий
это ответ
Здравствуйте, Минус!
Вы же не предусматриваете сохранения исходного положения. Точнее движение то работает с копией массива. А вот в процедуре сдвига вы изначально хоть присваиваете внутреннему указателю значение указателя основного массива вершин (хотя это верх наглости - сначала выделить НОВУЮ память под массив из n структур типа POINT, а потом единственный указатель на эту память затереть другим значением - утечка гарантирована, да еще и при каждом вызове процедуры движения), однако затем вы по этому укзателю и работаете, то есть вы изменяете значения координат изначальных вершин.
Могу предложить тщательно почистить код - ооочень много лишнего и использовать следующую схему работы:
в каждой процедуре изменения многоугольника копировать САМ массив а НЕ его указатель в локальный, работать с ним можно и как сейчас в принципе и потом обязательно удалять после использования. Во всяком случае если вы не под .NET работаете - это там сборщик мусора естьи то я лично пока его в работе тщательно не опробовал, по-этому не буду советовать ему доверять.
Форма ответа