Forum » Programiranje » Izračun normale v C++ in povezava z Excelom
Izračun normale v C++ in povezava z Excelom
K45P ::
Lep pozdrav. V C++ imam spodnji program. Z njim želim izračunati normalo poligonske površine (ukrivljena površina, omejena s 4 točkami). Te elemente imam nastavljene v Excelu, prilagam fotko. Ali je spodnji program sploh pravilen za to (drugače sem strojnica, in žal tega na faksu nimamo čisto nič :P). Opomba, ne delam s tremi točkami, ampak 4 (da je normala pravilno izračunana). Želela bi tudi narediti tako, da bi program jemal podatke iz Excela, nekaj sem sicer sama poskušala, a ni bilo preveč uspešno. Za vsakršne pripombe ali lažje variante bom zelo hvaležna! K.
http://postimg.org/image/d57nps5s7/
#import "C:\Users\Uporabnik\Desktop\Orodjarna\Moja diploma\ALOT1.xlsx" \
// the normal point
var x:Number = 0;
var y:Number = 0;
var z:Number = 0;
// if is a triangle with 3 points
if (points.length == 3) {
// read vertices of triangle
var Ax:Number, Bx:Number, Cx:Number;
var Ay:Number, By:Number, Cy:Number;
var Az:Number, Bz:Number, Cz:Number;
Ax = points[0].x; Bx = points[1].x; Cx = points[2].x;
Ay = points[0].y; By = points[1].y; Cy = points[2].y;
Az = points[0].z; Bz = points[1].z; Cz = points[2].z;
// calculate normal of a triangle
x = (By - Ay) * (Cz - Az) - (Bz - Az) * (Cy - Ay);
y = (Bz - Az) * (Cx - Ax) - (Bx - Ax) * (Cz - Az);
z = (Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax);
// if is a polygon with 4+ points
}else if (points.length > 3){
// calculate normal of a polygon using all points
var n:int = points.length;
x = 0;
y = 0;
z = 0
// ensure all points above 0
var minx:Number = 0, miny:Number = 0, minz:Number = 0;
for (var p:int = 0, pl:int = points.length; p < pl; p++) {
var po:_Point3D = points[p] = points[p].clone();
if (po.x < minx) { minx = po.x; }
if (po.y < miny) { miny = po.y; }
if (po.z < minz) { minz = po.z; }
}
if (minx > 0 || miny > 0 || minz > 0){
for (p = 0; p < pl; p++)
po = points[p];
po.x -= minx;
po.y -= miny;
po.z -= minz;
}
}
var cur:int = 1, prev:int = 0, next:int = 2;
for (var i:int = 1; i < n; i++) {
// using Newell method
x += points[cur].y * (points[next].z - points[prev].z);
y += points[cur].z * (points[next].x - points[prev].x);
z += points[cur].x * (points[next].y - points[prev].y);
cur = (cur+1) % n;
next = (next+1) % n;
prev = (prev+1) % n;
}
}
// length of the normal
var length:Number = Math.sqrt(x * x + y * y + z * z);
// if area is 0
if (length == 0) {
return null;
}else{
// turn large values into a unit vector
x = x / length;
y = y / length;
z = z / length;
}
http://postimg.org/image/d57nps5s7/
#import "C:\Users\Uporabnik\Desktop\Orodjarna\Moja diploma\ALOT1.xlsx" \
// the normal point
var x:Number = 0;
var y:Number = 0;
var z:Number = 0;
// if is a triangle with 3 points
if (points.length == 3) {
// read vertices of triangle
var Ax:Number, Bx:Number, Cx:Number;
var Ay:Number, By:Number, Cy:Number;
var Az:Number, Bz:Number, Cz:Number;
Ax = points[0].x; Bx = points[1].x; Cx = points[2].x;
Ay = points[0].y; By = points[1].y; Cy = points[2].y;
Az = points[0].z; Bz = points[1].z; Cz = points[2].z;
// calculate normal of a triangle
x = (By - Ay) * (Cz - Az) - (Bz - Az) * (Cy - Ay);
y = (Bz - Az) * (Cx - Ax) - (Bx - Ax) * (Cz - Az);
z = (Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax);
// if is a polygon with 4+ points
}else if (points.length > 3){
// calculate normal of a polygon using all points
var n:int = points.length;
x = 0;
y = 0;
z = 0
// ensure all points above 0
var minx:Number = 0, miny:Number = 0, minz:Number = 0;
for (var p:int = 0, pl:int = points.length; p < pl; p++) {
var po:_Point3D = points[p] = points[p].clone();
if (po.x < minx) { minx = po.x; }
if (po.y < miny) { miny = po.y; }
if (po.z < minz) { minz = po.z; }
}
if (minx > 0 || miny > 0 || minz > 0){
for (p = 0; p < pl; p++)
po = points[p];
po.x -= minx;
po.y -= miny;
po.z -= minz;
}
}
var cur:int = 1, prev:int = 0, next:int = 2;
for (var i:int = 1; i < n; i++) {
// using Newell method
x += points[cur].y * (points[next].z - points[prev].z);
y += points[cur].z * (points[next].x - points[prev].x);
z += points[cur].x * (points[next].y - points[prev].y);
cur = (cur+1) % n;
next = (next+1) % n;
prev = (prev+1) % n;
}
}
// length of the normal
var length:Number = Math.sqrt(x * x + y * y + z * z);
// if area is 0
if (length == 0) {
return null;
}else{
// turn large values into a unit vector
x = x / length;
y = y / length;
z = z / length;
}
technolog ::
Ne punca, ne bo šlo tko lahko. Bolj se boš morala posvetit problemu. Kot prvo, kako je lahko ukrivljena površina predstavljena s štirimi točkami? Gre za bezierovo ploskev?
Kot drugo, ta program niti približno ne počne tega. Kot tretje, ne moreš kar tako uvažat xls datotek v c++ program. Misliš, da lahko narediš karkoli se ti posveti in bo zadeva magično delala? Kje si dobila idejo, da lahko .xls datoteko vpišeš kar v import?
Problem rešiš tako, da .xls izvoziš v .CSV datoteko in jo potem prebereš v programu vrstico po vrstico.
Kot drugo, ta program niti približno ne počne tega. Kot tretje, ne moreš kar tako uvažat xls datotek v c++ program. Misliš, da lahko narediš karkoli se ti posveti in bo zadeva magično delala? Kje si dobila idejo, da lahko .xls datoteko vpišeš kar v import?
Problem rešiš tako, da .xls izvoziš v .CSV datoteko in jo potem prebereš v programu vrstico po vrstico.
jure3000 ::
Njena ploskev je razdeljena na elemente, vsak element ima 4 vozlišča, torej je štirikotnik v prostoru (če so vsa 4 vozlišča na isti ravnini). Torej lahko za ta štiri vozlišča izračunaš ravnino ter normalo ravnine.
Jaz se v kodo nisem poglabljal, tako da ne vem če prav izračuna normalo.
Za povezavo c++ excel uporabi google, jaz sem na hitro poiskal in sem prišo npr do tega linka: http://www.codeproject.com/Articles/158...
Jaz se v kodo nisem poglabljal, tako da ne vem če prav izračuna normalo.
Za povezavo c++ excel uporabi google, jaz sem na hitro poiskal in sem prišo npr do tega linka: http://www.codeproject.com/Articles/158...
Zgodovina sprememb…
- spremenilo: jure3000 ()
St753 ::
Če še nisi programirala, potem bo mogoče lažje začeti v Pythonu. Za branje in pisanje xls datotek je za Python na voljo več različnih modulov, ki so precej enostavni za uporabo.
K45P ::
Žal točke niso na isti ravnini, tisto bi bilo tudi izvedljivo v excelu za zračunat, ploskev niti ni natančno določena, dobi se iz globokega vleka, in jo je težje opredeliti kot bezierovo ali karkoli podobnega. Odgovor technologu: probavam samo tisto, kar sem našla na internetu uporabnega, kot sem že zgoraj omenila, žal nas tega niso učili, in tudi ne morem ravno vedeti točno kaj se da in kaj ne. Ni potrebe po nekem žaljivem tonu. jure3000 hvala za kodo, bom poiskala, prav tako bom pogledala Pythona.
noraguta ::
Zakaj se tega ne da zračunat v excelu ne razumem tocno.
Pust' ot pobyedy k pobyedye vyedyot!
technolog ::
Tud brez VBA se da. Simuliraš izraze s formulami, for zanke pa tako, da celico potegneš dol.
Jaz še vedno predlagam, da rezultate izvoziš v CSV, potem pa jih odpreš s poljubnim programskim jezikom.
Jaz še vedno predlagam, da rezultate izvoziš v CSV, potem pa jih odpreš s poljubnim programskim jezikom.
Zgodovina sprememb…
- spremenil: technolog ()
noraguta ::
Tud brez VBA se da. Simuliraš izraze s formulami, for zanke pa tako, da celico potegneš dol.
Jaz še vedno predlagam, da rezultate izvoziš v CSV, potem pa jih odpreš s poljubnim programskim jezikom.
dejmo komplicirat, če se le da.
Pust' ot pobyedy k pobyedye vyedyot!
Isotropic ::
delaš to pri štoku slučajno? magistrsko?
če je to abaqus, si raje poglej python, laho prek API direkt dostopaš do vseh podatkov o vozliščih - koordinate, E, S...
lahko poveš kaj konkretno delaš
če je to abaqus, si raje poglej python, laho prek API direkt dostopaš do vseh podatkov o vozliščih - koordinate, E, S...
lahko poveš kaj konkretno delaš
Zgodovina sprememb…
- spremenil: Isotropic ()
jure3000 ::
Normalo na ploskev se vedno računa v točki - v različnih točkah je normala različna. Torej vhod v algoritem vrjetno predstavljajo koordinate x y z, v katerih bi rada dobila normalo na ploskev.
Jaz bi normalo v tvojem primeru izračunal po takem algoritmu:
1. Izračunaj normale vseh tvojih elementov
1.1 Za vsak element izračunaj 4 normale na ploskve, ki jih določajo trikotniki elementa (štirikotnik razdeliš na 2 trikotnika, 2 možnosti - štirikotnik ima 2 diagonali, torej skupaj 4 različni trikotniki)
1.2 Če so normale elementa precej različne, to pomeni da so tvoji elementi precej nepravilne oblike, zato moreš bit pri takih elementih previdna, če boš jih uporabljala za FEM analizo. Če se normalne ne razlikujejo tako bistveno, izračunaš povprečno normalo ter imaš normalo elementa.
1.3 Shrani normale vseh 4 trikotnikov (po želji, za lažji pregled koliko se normale razlikujejo) oz povprečno normalo v celice pri elementu.
2. Ugotovi, v katerem elementu ležijo koordinate x,y,z, normala na ploskev je enaka normali v tem elementu
Prvo točko lahko brez problema izračunaš samo z excel funkcijami
Za drugo točko boš morala malo poiskat po googlu za algoritem. Algoritem bi moral zgledat tako: za vsako stranico štirikotnika preveri, če točka leži na levi ali desni strani stranice. Če leži na desni oz levi strani vseh stranic, leži znotraj štirikotnika. Pri tem je pomembno, kako so vozlišča razporejena (da so urejena, npr v smeri urinega kazalca ali nasprotni, od tega je odvisno ali morajo točke ležati na desni ali levi strani stranice).
Vsekakor pa če boš s programiranjem rešila problem, je najlažja možnost VBA znotraj excela.
Druga možnost pa je:
1. ugotovi v katerem štirikotniku leži točka
2. ugotovi v katerih dveh trikotnikih (ko štirikotnik razdeliš na 2 trikotnika) leži točka
3. Izračunaj normali obeh trikotnikov in ju povpreči.
Jaz bi normalo v tvojem primeru izračunal po takem algoritmu:
1. Izračunaj normale vseh tvojih elementov
1.1 Za vsak element izračunaj 4 normale na ploskve, ki jih določajo trikotniki elementa (štirikotnik razdeliš na 2 trikotnika, 2 možnosti - štirikotnik ima 2 diagonali, torej skupaj 4 različni trikotniki)
1.2 Če so normale elementa precej različne, to pomeni da so tvoji elementi precej nepravilne oblike, zato moreš bit pri takih elementih previdna, če boš jih uporabljala za FEM analizo. Če se normalne ne razlikujejo tako bistveno, izračunaš povprečno normalo ter imaš normalo elementa.
1.3 Shrani normale vseh 4 trikotnikov (po želji, za lažji pregled koliko se normale razlikujejo) oz povprečno normalo v celice pri elementu.
2. Ugotovi, v katerem elementu ležijo koordinate x,y,z, normala na ploskev je enaka normali v tem elementu
Prvo točko lahko brez problema izračunaš samo z excel funkcijami
Za drugo točko boš morala malo poiskat po googlu za algoritem. Algoritem bi moral zgledat tako: za vsako stranico štirikotnika preveri, če točka leži na levi ali desni strani stranice. Če leži na desni oz levi strani vseh stranic, leži znotraj štirikotnika. Pri tem je pomembno, kako so vozlišča razporejena (da so urejena, npr v smeri urinega kazalca ali nasprotni, od tega je odvisno ali morajo točke ležati na desni ali levi strani stranice).
Vsekakor pa če boš s programiranjem rešila problem, je najlažja možnost VBA znotraj excela.
Druga možnost pa je:
1. ugotovi v katerem štirikotniku leži točka
2. ugotovi v katerih dveh trikotnikih (ko štirikotnik razdeliš na 2 trikotnika) leži točka
3. Izračunaj normali obeh trikotnikov in ju povpreči.
Zgodovina sprememb…
- spremenilo: jure3000 ()
Isotropic ::
v abq tut normale ni tezko izračunat, k ti v manualu piše, kako so definirani elementi (orientacija). potem pa samo še python + api.
ne komplicirat z excelom in cpp.
ne komplicirat z excelom in cpp.
K45P ::
Nameravala sem isto narediti ko je opisal jure3000. Delam z ESI PAM - STAMP 2G, globoki vlek. V excelu sem normale tudi izračunala, a so precej različne (dva trikotnika, vsak ima svojo normalo). Problem bo namreč nastal kasneje v Catii oz. Siemens NX, ko bom te parametre vstavila noter in naredila površino na podlagi teh. Mora biti natančnost na stotinko milimetra, in mi lahko površino zlomi oziroma se naredi razpoka, če ne bodo točke pravilno kopirane glede na normalo in podano debelino. Razmišljam da bi quad razdelila na dva trikotnika, vsakemu poiskala središče, normale tako imam, in s tem potem nadaljevala. Vse to lahko res naredim v excelu, na dost enostaven način.
Isotropic ::
ce so elementi kvadratni (8 vozlisc), bodo kar problemi z normalami.
če so pa linearni (kvadratki), ima pa vsak tak trikotnik samo 2 orientaciji normal, glede na smer izbranih vozlišč pač.
drugače imajo vsi modelerji orodja za popravljanje ravno takih razpok, tko da se prezgodaj sekiraš imo.
če so pa linearni (kvadratki), ima pa vsak tak trikotnik samo 2 orientaciji normal, glede na smer izbranih vozlišč pač.
drugače imajo vsi modelerji orodja za popravljanje ravno takih razpok, tko da se prezgodaj sekiraš imo.
primoz4p ::
"Žal točke niso na isti ravnini, tisto bi bilo tudi izvedljivo v excelu za zračunat, ploskev niti ni natančno določena, dobi se iz globokega vleka, in jo je težje opredeliti kot bezierovo ali karkoli podobnega."
Predpostavljam, da imas strukturirano mrežo, iz česar sledi, da ni problem določiti točke za (Bezierove) zlepke. Pri določitvi teh točk imaš več možnosti. Z samo postavitvijo določaš ali gre Bezirjeva površina preko vozlišč ali preko sredin robov elementov in sam radij ukrivljenosti.
Glede na to, da ti ne potrebuješ funkcijsko odvisnost normale od položaja saj tudi samo obliko nimaš funkcijsko opisano (ampak samo vozlišča - točke) in za v Catio poterebuješ samo položaj točk, debelino in normalo v njih, bi jaz na tvojem mestu odločil za dve drugi možnosti in ju za oceno napake primerjal med seboj:
A) izračun normale in debeline na sredini 4 vozliščnega elementa
B) povprečenje normal elementov s skupnim vozliščem v le-tem in seveda noraliziranje povprečja.
A) Varianta:
Točka:
(xyz1+xyz2+xyz3+xyz4)/4
Debelina:
(
Norm[Cross[xyz4-xyz1,xyz2-xyz1]]*h1+
Norm[Cross[xyz1-xyz2,xyz3-xyz2]]*h2+
Norm[Cross[xyz2-xyz3,xyz4-xyz3]]*h3+
Norm[Cross[xyz3-xyz4,xyz1-xyz4]]*h4
)/(
Norm[Cross[xyz4-xyz1,xyz2-xyz1]]+
Norm[Cross[xyz1-xyz2,xyz3-xyz2]]+
Norm[Cross[xyz2-xyz3,xyz4-xyz3]]+Norm[Cross[xyz3-xyz4,xyz1-xyz4]]
)
Normala:
(
Cross[xyz4-xyz1,xyz2-xyz1]+
Cross[xyz1-xyz2,xyz3-xyz2]+
Cross[xyz2-xyz3,xyz4-xyz3]+
Cross[xyz3-xyz4,xyz1-xyz4]
)/Norm[
Cross[xyz4-xyz1,xyz2-xyz1]+
Cross[xyz1-xyz2,xyz3-xyz2]+
Cross[xyz2-xyz3,xyz4-xyz3]+
Cross[xyz3-xyz4,xyz1-xyz4]
]
Pri tem moras paziti, da si vozlisca (1,2,3,4) sledijo v (nasprotni)smeri gibanja urinega kazalca.
Pri debelini in normali je osnova: Integral veličine po površini deljeno z integralom površine.
"Norm" je oznaka za normo
"Cross" je oznaka za vektorski produkt
B) Varianta:
Točka:
xyzI
Debelina:
hI
Normala:
normalaIelementA = Cross[xyzI1ElementA-xyzI,xyzI2ElementA-xyz1]/Norm[Cross[xyzI1ElementA-xyzI,xyzI2ElementA-xyz1]]
normalaIelementB = Cross[xyzI1ElementB-xyzI,xyzI2ElementB-xyz1]/Norm[Cross[xyzI1ElementB-xyzI,xyzI2ElementB-xyz1]]
normalaIelementC = ...
normala = (normalaIelementA + normalaIelementB +...)/Norm[(normalaIelementA + normalaIelementB +...)]
---------
Se nekaj o povezavi med Excelom in C++
Iz tvoje fotke vidim samo topologijo elementov (katera vozlisca pripadajo posameznim elementom) in (povprečja?) debelino. Ni pa podatka o samih končnih koordinatah vozlišč. Iz tega predpostavljam, da ti sama naredila ta Excel.
Se pravi, da obstaja ena ali več originalnih datotek z rezultati analize v ASCII ali znanem binarnem formatu.
Moje vprašanje tu je, zakaj teh originalnih datotek ne uvoziš v C++ in šele po obdelavi v Excel oziroma zakaj Excel -> C++ ->Excel?
V kolikor uporabljaš Excel za lažjo predstavo (grafičen prikaz), ti resno svetujm razmislek o uporabi Matlaba, Wolfram Mathematica, ... namesto kombinacije Excel - C++
Predpostavljam, da imas strukturirano mrežo, iz česar sledi, da ni problem določiti točke za (Bezierove) zlepke. Pri določitvi teh točk imaš več možnosti. Z samo postavitvijo določaš ali gre Bezirjeva površina preko vozlišč ali preko sredin robov elementov in sam radij ukrivljenosti.
Glede na to, da ti ne potrebuješ funkcijsko odvisnost normale od položaja saj tudi samo obliko nimaš funkcijsko opisano (ampak samo vozlišča - točke) in za v Catio poterebuješ samo položaj točk, debelino in normalo v njih, bi jaz na tvojem mestu odločil za dve drugi možnosti in ju za oceno napake primerjal med seboj:
A) izračun normale in debeline na sredini 4 vozliščnega elementa
B) povprečenje normal elementov s skupnim vozliščem v le-tem in seveda noraliziranje povprečja.
A) Varianta:
Točka:
(xyz1+xyz2+xyz3+xyz4)/4
Debelina:
(
Norm[Cross[xyz4-xyz1,xyz2-xyz1]]*h1+
Norm[Cross[xyz1-xyz2,xyz3-xyz2]]*h2+
Norm[Cross[xyz2-xyz3,xyz4-xyz3]]*h3+
Norm[Cross[xyz3-xyz4,xyz1-xyz4]]*h4
)/(
Norm[Cross[xyz4-xyz1,xyz2-xyz1]]+
Norm[Cross[xyz1-xyz2,xyz3-xyz2]]+
Norm[Cross[xyz2-xyz3,xyz4-xyz3]]+Norm[Cross[xyz3-xyz4,xyz1-xyz4]]
)
Normala:
(
Cross[xyz4-xyz1,xyz2-xyz1]+
Cross[xyz1-xyz2,xyz3-xyz2]+
Cross[xyz2-xyz3,xyz4-xyz3]+
Cross[xyz3-xyz4,xyz1-xyz4]
)/Norm[
Cross[xyz4-xyz1,xyz2-xyz1]+
Cross[xyz1-xyz2,xyz3-xyz2]+
Cross[xyz2-xyz3,xyz4-xyz3]+
Cross[xyz3-xyz4,xyz1-xyz4]
]
Pri tem moras paziti, da si vozlisca (1,2,3,4) sledijo v (nasprotni)smeri gibanja urinega kazalca.
Pri debelini in normali je osnova: Integral veličine po površini deljeno z integralom površine.
"Norm" je oznaka za normo
"Cross" je oznaka za vektorski produkt
B) Varianta:
Točka:
xyzI
Debelina:
hI
Normala:
normalaIelementA = Cross[xyzI1ElementA-xyzI,xyzI2ElementA-xyz1]/Norm[Cross[xyzI1ElementA-xyzI,xyzI2ElementA-xyz1]]
normalaIelementB = Cross[xyzI1ElementB-xyzI,xyzI2ElementB-xyz1]/Norm[Cross[xyzI1ElementB-xyzI,xyzI2ElementB-xyz1]]
normalaIelementC = ...
normala = (normalaIelementA + normalaIelementB +...)/Norm[(normalaIelementA + normalaIelementB +...)]
---------
Se nekaj o povezavi med Excelom in C++
Iz tvoje fotke vidim samo topologijo elementov (katera vozlisca pripadajo posameznim elementom) in (povprečja?) debelino. Ni pa podatka o samih končnih koordinatah vozlišč. Iz tega predpostavljam, da ti sama naredila ta Excel.
Se pravi, da obstaja ena ali več originalnih datotek z rezultati analize v ASCII ali znanem binarnem formatu.
Moje vprašanje tu je, zakaj teh originalnih datotek ne uvoziš v C++ in šele po obdelavi v Excel oziroma zakaj Excel -> C++ ->Excel?
V kolikor uporabljaš Excel za lažjo predstavo (grafičen prikaz), ti resno svetujm razmislek o uporabi Matlaba, Wolfram Mathematica, ... namesto kombinacije Excel - C++
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | SQL backup importOddelek: Programiranje | 1060 (862) | meh |
» | Debian in sftpOddelek: Operacijski sistemi | 1020 (960) | OmegaBlue |
» | zapeka fila kot imageOddelek: Pomoč in nasveti | 1014 (945) | nonenone |
» | VisualBasicScript za download informacij iz internetaOddelek: Programiranje | 1128 (1074) | darkolord |
» | wordOddelek: Loža | 1017 (951) | McHusch |