14 : className(
"ViewCell"),
19 hasExternalCanvas(false),
29 plotMeshBorders(false),
40 axes->SetStats(
false);
41 axes->GetXaxis()->SetTitle(
"x");
42 axes->GetYaxis()->SetTitle(
"y");
47 if (!hasExternalCanvas && canvas != 0)
delete canvas;
53 std::cerr << className <<
"::SetComponent:\n";
54 std::cerr <<
" Component pointer is null.\n";
64 if (!hasExternalCanvas && canvas != 0) {
69 hasExternalCanvas =
true;
75 double ymax,
double zmax) {
78 if (xmin == xmax || ymin == ymax) {
79 std::cout << className <<
"::SetArea:\n";
80 std::cout <<
" Null area range not permitted.\n";
83 xMin = std::min(xmin, xmax);
84 yMin = std::min(ymin, ymax);
85 zMin = std::min(zmin, zmax);
86 xMax = std::max(xmin, xmax);
87 yMax = std::max(ymin, ymax);
88 zMax = std::max(zmin, zmax);
100 std::cerr << className <<
"::Plot:\n";
101 std::cerr <<
" Component is not defined.\n";
105 double pmin = 0., pmax = 0.;
107 std::cerr << className <<
"::Plot:\n";
108 std::cerr <<
" Component is not ready.\n";
114 std::cerr << className <<
"::Plot:\n";
115 std::cerr <<
" Bounding box cannot be determined.\n";
116 std::cerr <<
" Call SetArea first.\n";
122 canvas =
new TCanvas();
123 canvas->SetTitle(label.c_str());
124 if (hasExternalCanvas) hasExternalCanvas =
false;
126 canvas->Range(xMin, yMin, xMax, yMax);
130 if (componentCST != 0) {
131 std::cout << className <<
"::Plot:\n";
132 std::cout <<
" The given component is a CST component.\n";
133 std::cout <<
" Method PlotCST is called now!.\n";
134 DrawCST(componentCST);
146 const double x0,
const double y0,
const double z0) {
149 double fnorm =
sqrt(fx * fx + fy * fy + fz * fz);
150 double dist = fx * x0 + fy * y0 + fz * z0;
151 if (fnorm > 0 && fx * fx + fz * fz > 0) {
152 project[0][0] = fz /
sqrt(fx * fx + fz * fz);
154 project[0][2] = -fx /
sqrt(fx * fx + fz * fz);
155 project[1][0] = -fx * fy / (
sqrt(fx * fx + fz * fz) * fnorm);
156 project[1][1] = (fx * fx + fz * fz) / (
sqrt(fx * fx + fz * fz) * fnorm);
157 project[1][2] = -fy * fz / (
sqrt(fx * fx + fz * fz) * fnorm);
158 project[2][0] = dist * fx / (fnorm * fnorm);
159 project[2][1] = dist * fy / (fnorm * fnorm);
160 project[2][2] = dist * fz / (fnorm * fnorm);
161 }
else if (fnorm > 0 && fy * fy + fz * fz > 0) {
162 project[0][0] = (fy * fy + fz * fz) / (
sqrt(fy * fy + fz * fz) * fnorm);
163 project[0][1] = -fx * fz / (
sqrt(fy * fy + fz * fz) * fnorm);
164 project[0][2] = -fy * fz / (
sqrt(fy * fy + fz * fz) * fnorm);
166 project[1][1] = fz /
sqrt(fy * fy + fz * fz);
167 project[1][2] = -fy /
sqrt(fy * fy + fz * fz);
168 project[2][0] = dist * fx / (fnorm * fnorm);
169 project[2][1] = dist * fy / (fnorm * fnorm);
170 project[2][2] = dist * fz / (fnorm * fnorm);
172 std::cout << className <<
"::SetPlane:\n";
173 std::cout <<
" Normal vector has zero norm.\n";
174 std::cout <<
" No new projection set.\n";
213 axes->GetXaxis()->SetTitle(xtitle);
218 axes->GetYaxis()->SetTitle(ytitle);
226 xMin + std::abs(xMax - xMin) * 0.1, yMin + std::abs(yMax - yMin) * 0.1,
227 xMax - std::abs(xMax - xMin) * 0.1, yMin + std::abs(yMax - yMin) * 0.1,
228 xMin + std::abs(xMax - xMin) * 0.1, xMax - std::abs(xMax - xMin) * 0.1,
231 xMin + std::abs(xMax - xMin) * 0.1, yMin + std::abs(yMax - yMin) * 0.1,
232 xMin + std::abs(xMax - xMin) * 0.1, yMax - std::abs(yMax - yMin) * 0.1,
233 yMin + std::abs(yMax - yMin) * 0.1, yMax - std::abs(yMax - yMin) * 0.1,
237 xaxis->SetLabelSize(0.025);
238 yaxis->SetLabelSize(0.025);
241 xaxis->SetTitleSize(0.03);
242 xaxis->SetTitle(
"x [cm]");
243 yaxis->SetTitleSize(0.03);
244 yaxis->SetTitle(
"y [cm]");
249void ViewFEMesh::DrawElements() {
252 double mapxmax = component->
mapxmax;
253 double mapxmin = component->
mapxmin;
254 double mapymax = component->
mapymax;
255 double mapymin = component->
mapymin;
256 double mapzmax = component->
mapzmax;
257 double mapzmin = component->
mapzmin;
260 double sx = mapxmax - mapxmin;
261 double sy = mapymax - mapymin;
262 double sz = mapzmax - mapzmin;
274 sqrt(plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]);
276 dataProj[0] = project[0][0];
277 dataProj[1] = project[1][0];
278 dataProj[2] = plane[0] / fnorm;
279 dataProj[3] = project[0][1];
280 dataProj[4] = project[1][1];
281 dataProj[5] = plane[1] / fnorm;
282 dataProj[6] = project[0][2];
283 dataProj[7] = project[1][2];
284 dataProj[8] = plane[2] / fnorm;
285 TMatrixD projMat(3, 3, dataProj.GetArray());
290 (projMat(1, 1) * projMat(2, 2) - projMat(1, 2) * projMat(2, 1)) -
292 (projMat(1, 0) * projMat(2, 2) - projMat(1, 2) * projMat(2, 0)) +
294 (projMat(1, 0) * projMat(2, 1) - projMat(1, 1) * projMat(2, 0));
301 std::cerr << className <<
"::DrawElements:\n";
302 std::cerr <<
" Projection matrix is not invertible.\n";
303 std::cerr <<
" Finite element mesh will not be drawn.\n";
307 double fx = plane[0];
308 double fy = plane[1];
309 double fz = plane[2];
310 double dist = plane[3];
316 int nMaxX = 0, nMinX = 0;
317 int nMaxY = 0, nMinY = 0;
318 int nMaxZ = 0, nMinZ = 0;
320 nMinX = int(xMin / sx) - 1;
321 nMaxX = int(xMax / sx) + 1;
324 nMinY = int(yMin / sy) - 1;
325 nMaxY = int(yMax / sy) + 1;
328 nMinZ = int(zMin / sz) - 1;
329 nMaxZ = int(zMax / sz) + 1;
333 for (
int elem = 0; elem < component->
nElements; elem++) {
340 if (disabledMaterial[component->
elements[elem].matmap])
continue;
344 double vx1, vy1, vz1;
345 double vx2, vy2, vz2;
346 double vx3, vy3, vz3;
347 double vx4, vy4, vz4;
350 int colorID = colorMap.count(component->
elements[elem].matmap);
352 colorID = colorMap[component->
elements[elem].matmap];
357 int colorID_fill = colorMap_fill.count(component->
elements[elem].matmap);
358 if (colorID_fill != 0)
359 colorID_fill = colorMap_fill[component->
elements[elem].matmap];
361 colorID_fill = colorID;
364 for (
int nx = nMinX; nx <= nMaxX; nx++) {
370 (mapxmax - component->
nodes[component->
elements[elem].emap[0]].x) +
374 (mapxmax - component->
nodes[component->
elements[elem].emap[1]].x) +
378 (mapxmax - component->
nodes[component->
elements[elem].emap[2]].x) +
382 (mapxmax - component->
nodes[component->
elements[elem].emap[3]].x) +
385 vx1 = component->
nodes[component->
elements[elem].emap[0]].x + sx * nx;
386 vx2 = component->
nodes[component->
elements[elem].emap[1]].x + sx * nx;
387 vx3 = component->
nodes[component->
elements[elem].emap[2]].x + sx * nx;
388 vx4 = component->
nodes[component->
elements[elem].emap[3]].x + sx * nx;
392 for (
int ny = nMinY; ny <= nMaxY; ny++) {
413 vy1 = component->
nodes[component->
elements[elem].emap[0]].y + sy * ny;
414 vy2 = component->
nodes[component->
elements[elem].emap[1]].y + sy * ny;
415 vy3 = component->
nodes[component->
elements[elem].emap[2]].y + sy * ny;
416 vy4 = component->
nodes[component->
elements[elem].emap[3]].y + sy * ny;
420 for (
int nz = nMinZ; nz <= nMaxZ; nz++) {
442 component->
nodes[component->
elements[elem].emap[0]].z + sz * nz;
444 component->
nodes[component->
elements[elem].emap[1]].z + sz * nz;
446 component->
nodes[component->
elements[elem].emap[2]].z + sz * nz;
448 component->
nodes[component->
elements[elem].emap[3]].z + sz * nz;
452 std::vector<double> vX;
453 std::vector<double> vY;
457 bool in1 =
false, in2 =
false, in3 =
false, in4 =
false;
460 bool planeCut =
false;
463 double pcf = std::max(
464 std::max(std::max(std::max(std::max(std::max(std::abs(vx1),
473 if (std::abs(fx * vx1 + fy * vy1 + fz * vz1 - dist) < 1.0e-4 * pcf) {
476 if (std::abs(fx * vx2 + fy * vy2 + fz * vz2 - dist) < 1.0e-4 * pcf) {
479 if (std::abs(fx * vx3 + fy * vy3 + fz * vz3 - dist) < 1.0e-4 * pcf) {
482 if (std::abs(fx * vx4 + fy * vy4 + fz * vz4 - dist) < 1.0e-4 * pcf) {
489 PlaneCoords(vx1, vy1, vz1, projMat, xMat);
490 vX.push_back(xMat(0, 0));
491 vY.push_back(xMat(1, 0));
494 PlaneCoords(vx2, vy2, vz2, projMat, xMat);
495 vX.push_back(xMat(0, 0));
496 vY.push_back(xMat(1, 0));
499 PlaneCoords(vx3, vy3, vz3, projMat, xMat);
500 vX.push_back(xMat(0, 0));
501 vY.push_back(xMat(1, 0));
504 PlaneCoords(vx4, vy4, vz4, projMat, xMat);
505 vX.push_back(xMat(0, 0));
506 vY.push_back(xMat(1, 0));
511 planeCut = PlaneCut(vx1, vy1, vz1, vx2, vy2, vz2, xMat);
513 vX.push_back(xMat(0, 0));
514 vY.push_back(xMat(1, 0));
518 planeCut = PlaneCut(vx1, vy1, vz1, vx3, vy3, vz3, xMat);
520 vX.push_back(xMat(0, 0));
521 vY.push_back(xMat(1, 0));
525 planeCut = PlaneCut(vx1, vy1, vz1, vx4, vy4, vz4, xMat);
527 vX.push_back(xMat(0, 0));
528 vY.push_back(xMat(1, 0));
532 planeCut = PlaneCut(vx2, vy2, vz2, vx3, vy3, vz3, xMat);
534 vX.push_back(xMat(0, 0));
535 vY.push_back(xMat(1, 0));
539 planeCut = PlaneCut(vx2, vy2, vz2, vx4, vy4, vz4, xMat);
541 vX.push_back(xMat(0, 0));
542 vY.push_back(xMat(1, 0));
546 planeCut = PlaneCut(vx3, vy3, vz3, vx4, vy4, vz4, xMat);
548 vX.push_back(xMat(0, 0));
549 vY.push_back(xMat(1, 0));
554 if (vX.size() >= 3) {
558 RemoveCrossings(vX, vY);
561 std::vector<double> cX;
562 std::vector<double> cY;
565 ClipToView(vX, vY, cX, cY);
571 RemoveCrossings(cX, cY);
575 TPolyLine* poly =
new TPolyLine();
576 poly->SetLineColor(colorID);
577 poly->SetFillColor(colorID_fill);
578 poly->SetLineWidth(3);
581 for (
int pt = 0; pt < (int)cX.size(); pt++) {
584 poly->SetPoint(polyPts, cX[pt], cY[pt]);
589 mesh.push_back(poly);
598 if (viewDrift != 0) {
600 for (
int dline = 0; dline < (int)viewDrift->m_driftLines.size(); dline++) {
603 const unsigned int npts = viewDrift->m_driftLines[dline].vect.size();
605 TPolyLine* poly =
new TPolyLine();
606 poly->SetLineColor(viewDrift->m_driftLines[dline].n);
608 for (
unsigned int pt = 0; pt < npts; pt++) {
610 double ptx = viewDrift->m_driftLines[dline].vect[pt].x;
611 double pty = viewDrift->m_driftLines[dline].vect[pt].y;
612 double ptz = viewDrift->m_driftLines[dline].vect[pt].z;
614 PlaneCoords(ptx, pty, ptz, projMat, xMat);
616 if (xMat(0, 0) >= xMin && xMat(0, 0) <= xMax && xMat(1, 0) >= yMin &&
617 xMat(1, 0) <= yMax) {
618 poly->SetPoint(polyPts, xMat(0, 0), xMat(1, 0));
624 driftLines.push_back(poly);
633 if (xaxis == 0 && yaxis == 0 && drawAxes) {
634 axes->GetXaxis()->SetLimits(xMin, xMax);
635 axes->GetYaxis()->SetLimits(yMin, yMax);
640 if (xaxis != 0 && drawAxes) xaxis->Draw();
641 if (yaxis != 0 && drawAxes) yaxis->Draw();
644 for (
int m = mesh.size(); m--;) {
645 if (plotMeshBorders || !fillMesh) mesh[m]->Draw(
"same");
646 if (fillMesh) mesh[m]->Draw(
"f:same");
650 for (
int m = driftLines.size(); m--;) {
651 driftLines[m]->Draw(
"same");
655void ViewFEMesh::DrawCST(ComponentCST* componentCST) {
665 double mapxmax = component->
mapxmax;
666 double mapxmin = component->
mapxmin;
667 double mapymax = component->
mapymax;
668 double mapymin = component->
mapymin;
669 double mapzmax = component->
mapzmax;
670 double mapzmin = component->
mapzmin;
673 double sx = mapxmax - mapxmin;
674 double sy = mapymax - mapymin;
675 double sz = mapzmax - mapzmin;
687 sqrt(plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]);
689 dataProj[0] = project[0][0];
690 dataProj[1] = project[1][0];
691 dataProj[2] = plane[0] / fnorm;
692 dataProj[3] = project[0][1];
693 dataProj[4] = project[1][1];
694 dataProj[5] = plane[1] / fnorm;
695 dataProj[6] = project[0][2];
696 dataProj[7] = project[1][2];
697 dataProj[8] = plane[2] / fnorm;
698 TMatrixD projMat(3, 3, dataProj.GetArray());
703 (projMat(1, 1) * projMat(2, 2) - projMat(1, 2) * projMat(2, 1)) -
705 (projMat(1, 0) * projMat(2, 2) - projMat(1, 2) * projMat(2, 0)) +
707 (projMat(1, 0) * projMat(2, 1) - projMat(1, 1) * projMat(2, 0));
714 std::cerr << className <<
"::DrawCST:\n";
715 std::cerr <<
" Projection matrix is not invertible.\n";
716 std::cerr <<
" Finite element mesh will not be drawn.\n";
723 int nMaxX = 0, nMinX = 0;
724 int nMaxY = 0, nMinY = 0;
725 int nMaxZ = 0, nMinZ = 0;
727 nMinX = int(xMin / sx) - 1;
728 nMaxX = int(xMax / sx) + 1;
731 nMinY = int(yMin / sy) - 1;
732 nMaxY = int(yMax / sy) + 1;
735 nMinZ = int(zMin / sz) - 1;
736 nMaxZ = int(zMax / sz) + 1;
740 std::vector<PolygonInfo> elements;
741 int nMinU = 0, nMaxU = 0, nMinV = 0, nMaxV = 0;
742 double mapumin = 0., mapumax = 0., mapvmin = 0., mapvmax = 0.;
743 double su = 0., sv = 0.;
744 bool mirroru =
false, mirrorv =
false;
745 double uMin, vMin, uMax, vMax;
746 unsigned int n_x, n_y, n_z;
747 componentCST->GetNumberOfMeshLines(n_x, n_y, n_z);
748 double e_xmin, e_xmax, e_ymin, e_ymax, e_zmin, e_zmax;
750 if (plane[0] == 0 && plane[1] == 0 && plane[2] == 1) {
751 std::cout << className <<
"::DrawCST:\n";
752 std::cout <<
" Creating x-y mesh view.\n";
757 if(!componentCST->Coordinate2Index(0,0,project[2][2],i,j,z)){
758 std::cerr <<
"Could determine the position of the plane in z direction." << std::endl;
761 std::cout <<
" The plane position in z direction is: " << project[2][2] <<
"\n";
779 for (
unsigned int y = 0; y < (n_y - 1); y++) {
780 for (
unsigned int x = 0; x < (n_x - 1); x++) {
781 elem = componentCST->Index2Element(x,y,z);
782 componentCST->GetElementBoundaries(elem, e_xmin, e_xmax, e_ymin, e_ymax, e_zmin, e_zmax);
783 PolygonInfo tmp_info;
784 tmp_info.element = elem;
785 tmp_info.p1[0] = e_xmin;
786 tmp_info.p2[0] = e_xmax;
787 tmp_info.p3[0] = e_xmax;
788 tmp_info.p4[0] = e_xmin;
789 tmp_info.p1[1] = e_ymin;
790 tmp_info.p2[1] = e_ymin;
791 tmp_info.p3[1] = e_ymax;
792 tmp_info.p4[1] = e_ymax;
793 tmp_info.material = componentCST->GetElementMaterial(elem);
794 elements.push_back(tmp_info);
798 }
else if (plane[0] == 0 && plane[1] == -1 && plane[2] == 0) {
799 std::cout << className <<
"::DrawCST:\n";
800 std::cout <<
" Creating x-z mesh view.\n";
804 unsigned int i = 0,j = 0,y = 0;
805 if(!componentCST->Coordinate2Index(0,project[2][1],0,i,y,j)){
806 std::cerr <<
"Could determine the position of the plane in y direction." << std::endl;
809 std::cout <<
" The plane position in y direction is: " << project[2][1] <<
"\n";
828 for (
unsigned int z = 0; z < (n_z - 1); z++) {
829 for (
unsigned int x = 0; x < (n_x - 1); x++) {
830 elem = componentCST->Index2Element(x,y,z);
831 componentCST->GetElementBoundaries(elem, e_xmin, e_xmax, e_ymin, e_ymax, e_zmin, e_zmax);
832 PolygonInfo tmp_info;
833 tmp_info.element = elem;
834 tmp_info.p1[0] = e_xmin;
835 tmp_info.p2[0] = e_xmax;
836 tmp_info.p3[0] = e_xmax;
837 tmp_info.p4[0] = e_xmin;
838 tmp_info.p1[1] = e_zmin;
839 tmp_info.p2[1] = e_zmin;
840 tmp_info.p3[1] = e_zmax;
841 tmp_info.p4[1] = e_zmax;
842 tmp_info.material = componentCST->GetElementMaterial(elem);
843 elements.push_back(tmp_info);
848 }
else if (plane[0] == -1 && plane[1] == 0 && plane[2] == 0) {
849 std::cout << className <<
"::DrawCST:\n";
850 std::cout <<
" Creating z-y mesh view.\n";
855 if(!componentCST->Coordinate2Index(project[2][0],0,0,x,i,j)){
856 std::cerr <<
"Could determine the position of the plane in x direction." << std::endl;
859 std::cout <<
" The plane position in x direction is: " << project[2][0] <<
"\n";
877 for (
unsigned int z = 0; z < (n_z-1); z++) {
878 for (
unsigned int y = 0; y < (n_y-1); y++) {
879 elem = componentCST->Index2Element(x,y,z);
880 componentCST->GetElementBoundaries(elem, e_xmin, e_xmax, e_ymin, e_ymax, e_zmin, e_zmax);
881 PolygonInfo tmp_info;
882 tmp_info.element = elem;
883 tmp_info.p1[0] = e_zmin;
884 tmp_info.p2[0] = e_zmax;
885 tmp_info.p3[0] = e_zmax;
886 tmp_info.p4[0] = e_zmin;
887 tmp_info.p1[1] = e_ymin;
888 tmp_info.p2[1] = e_ymin;
889 tmp_info.p3[1] = e_ymax;
890 tmp_info.p4[1] = e_ymax;
891 tmp_info.material = componentCST->GetElementMaterial(elem);
893 elements.push_back(tmp_info);
897 std::cerr << className <<
"::DrawCST:\n";
898 std::cerr <<
" The given plane name is not known.\n";
899 std::cerr <<
" Please choose one of the following: xy, xz, yz.\n";
902 std::cout << className <<
"::PlotCST:\n";
903 std::cout <<
" Number of elements in the projection of the unit cell:"
904 << elements.size() << std::endl;
905 std::vector<PolygonInfo>::iterator it;
906 std::vector<PolygonInfo>::iterator itend = elements.end();
908 for (
int nu = nMinU; nu <= nMaxU; nu++) {
909 for (
int nv = nMinV; nv <= nMaxV; nv++) {
910 it = elements.begin();
911 while (it != itend) {
912 if (disabledMaterial[(*it).material]) {
917 int colorID = colorMap.count((*it).material);
919 colorID = colorMap[(*it).material];
924 int colorID_fill = colorMap_fill.count((*it).material);
925 if (colorID_fill != 0)
926 colorID_fill = colorMap_fill[(*it).material];
928 colorID_fill = colorID;
930 TPolyLine* poly =
new TPolyLine();
931 poly->SetLineColor(colorID);
932 poly->SetFillColor(colorID_fill);
934 poly->SetLineWidth(3);
936 poly->SetLineWidth(1);
938 Double_t tmp_u[4], tmp_v[4];
939 if (mirroru && nu != 2 * (nu / 2)) {
941 tmp_u[0] = mapumin + (mapumax - (*it).p1[0]) + su * nu;
942 tmp_u[1] = mapumin + (mapumax - (*it).p2[0]) + su * nu;
943 tmp_u[2] = mapumin + (mapumax - (*it).p3[0]) + su * nu;
944 tmp_u[3] = mapumin + (mapumax - (*it).p4[0]) + su * nu;
947 tmp_u[0] = (*it).p1[0] + su * nu;
948 tmp_u[1] = (*it).p2[0] + su * nu;
949 tmp_u[2] = (*it).p3[0] + su * nu;
950 tmp_u[3] = (*it).p4[0] + su * nu;
952 if (mirrorv && nv != 2 * (nv / 2)) {
953 tmp_v[0] = mapvmin + (mapvmax - (*it).p1[1]) + sv * nv;
954 tmp_v[1] = mapvmin + (mapvmax - (*it).p2[1]) + sv * nv;
955 tmp_v[2] = mapvmin + (mapvmax - (*it).p3[1]) + sv * nv;
956 tmp_v[3] = mapvmin + (mapvmax - (*it).p4[1]) + sv * nv;
958 tmp_v[0] = (*it).p1[1] + sv * nv;
959 tmp_v[1] = (*it).p2[1] + sv * nv;
960 tmp_v[2] = (*it).p3[1] + sv * nv;
961 tmp_v[3] = (*it).p4[1] + sv * nv;
963 if(tmp_u[0] < uMin || tmp_u[1] > uMax || tmp_v[0] < vMin || tmp_v[2] > vMax){
967 poly->SetPoint(0, tmp_u[0], tmp_v[0]);
968 poly->SetPoint(1, tmp_u[1], tmp_v[1]);
969 poly->SetPoint(2, tmp_u[2], tmp_v[2]);
970 poly->SetPoint(3, tmp_u[3], tmp_v[3]);
972 mesh.push_back(poly);
977 std::cout << className <<
"::PlotCST:\n";
978 std::cout <<
" Number of polygons to be drawn:"
979 << mesh.size() << std::endl;
981 if (viewDrift != 0) {
983 for (
int dline = 0; dline < (int)viewDrift->m_driftLines.size(); dline++) {
986 const unsigned int npts = viewDrift->m_driftLines[dline].vect.size();
988 TPolyLine* poly =
new TPolyLine();
989 poly->SetLineColor(viewDrift->m_driftLines[dline].n);
991 for (
unsigned int pt = 0; pt < npts; pt++) {
993 double ptx = viewDrift->m_driftLines[dline].vect[pt].x;
994 double pty = viewDrift->m_driftLines[dline].vect[pt].y;
995 double ptz = viewDrift->m_driftLines[dline].vect[pt].z;
997 PlaneCoords(ptx, pty, ptz, projMat, xMat);
999 if (xMat(0, 0) >= uMin && xMat(0, 0) <= uMax && xMat(1, 0) >= vMin &&
1000 xMat(1, 0) <= vMax) {
1001 poly->SetPoint(polyPts, xMat(0, 0), xMat(1, 0));
1006 driftLines.push_back(poly);
1013 if (xaxis == 0 && yaxis == 0 && drawAxes) {
1014 axes->GetXaxis()->SetLimits(uMin, uMax);
1015 axes->GetYaxis()->SetLimits(vMin, vMax);
1019 if (xaxis != 0 && drawAxes) xaxis->Draw(
"");
1020 if (yaxis != 0 && drawAxes) yaxis->Draw(
"");
1022 for (
int m = mesh.size(); m--;) {
1023 if (plotMeshBorders || !fillMesh) mesh[m]->Draw(
"same");
1024 if (fillMesh) mesh[m]->Draw(
"f:sames");
1028 for (
int m = driftLines.size(); m--;) {
1029 driftLines[m]->Draw(
"sames");
1035bool ViewFEMesh::InView(
double x,
double y) {
1036 return (x >= xMin && x <= xMax && y >= yMin && y <= yMax);
1045void ViewFEMesh::RemoveCrossings(std::vector<double>& x,
1046 std::vector<double>& y) {
1049 double xmin = x[0], xmax = x[0];
1050 double ymin = y[0], ymax = y[0];
1051 for (
int i = 1; i < (int)x.size(); i++) {
1052 if (x[i] < xmin) xmin = x[i];
1053 if (x[i] > xmax) xmax = x[i];
1054 if (y[i] < ymin) ymin = y[i];
1055 if (y[i] > ymax) ymax = y[i];
1059 double xtol = 1e-10 * std::abs(xmax - xmin);
1060 double ytol = 1e-10 * std::abs(ymax - ymin);
1061 for (
int i = 0; i < (int)x.size(); i++) {
1062 for (
int j = i + 1; j < (int)x.size(); j++) {
1063 if (std::abs(x[i] - x[j]) < xtol && std::abs(y[i] - y[j]) < ytol) {
1064 x.erase(x.begin() + j);
1065 y.erase(y.begin() + j);
1072 if (x.size() <= 3)
return;
1082 bool crossings =
true;
1083 while (crossings && (attempts < NN)) {
1088 for (
int i = 1; i <= NN; i++) {
1089 for (
int j = i + 2; j <= NN; j++) {
1092 if ((j + 1) > NN && 1 + (j % NN) >= i)
break;
1098 double xc = 0., yc = 0.;
1099 if (LinesCrossed(x[(i - 1) % NN], y[(i - 1) % NN], x[i % NN],
1100 y[i % NN], x[(j - 1) % NN], y[(j - 1) % NN],
1101 x[j % NN], y[j % NN], xc, yc)) {
1105 for (
int k = 1; k <= (j - i) / 2; k++) {
1107 double xs = x[(i + k - 1) % NN];
1108 double ys = y[(i + k - 1) % NN];
1109 x[(i + k - 1) % NN] = x[(j - k) % NN];
1110 y[(i + k - 1) % NN] = y[(j - k) % NN];
1111 x[(j - k) % NN] = xs;
1112 y[(j - k) % NN] = ys;
1127 if (attempts > NN) {
1128 std::cerr << className <<
"::RemoveCrossings:\n";
1130 <<
" WARNING: Maximum attempts reached - crossings not removed.\n";
1141bool ViewFEMesh::LinesCrossed(
double x1,
double y1,
double x2,
double y2,
1142 double u1,
double v1,
double u2,
double v2,
1143 double& xc,
double& yc) {
1148 std::max(std::abs(x1),
1149 std::max(std::abs(x2), std::max(std::abs(u1), std::abs(u2))));
1152 std::max(std::abs(y1),
1153 std::max(std::abs(y2), std::max(std::abs(v1), std::abs(v2))));
1154 if (xtol <= 0) xtol = 1.0e-10;
1155 if (ytol <= 0) ytol = 1.0e-10;
1158 double dy = y2 - y1;
1159 double dv = v2 - v1;
1160 double dx = x1 - x2;
1161 double du = u1 - u2;
1162 double det = dy * du - dx * dv;
1165 if (OnLine(x1, y1, x2, y2, u1, v1)) {
1169 }
else if (OnLine(x1, y1, x2, y2, u2, v2)) {
1173 }
else if (OnLine(u1, v1, u2, v2, x1, y1)) {
1177 }
else if (OnLine(u1, v1, u2, v2, x2, y2)) {
1183 else if (std::abs(det) < xtol * ytol)
1189 xc = (du * (x1 * y2 - x2 * y1) - dx * (u1 * v2 - u2 * v1)) / det;
1190 yc = ((-1 * dv) * (x1 * y2 - x2 * y1) + dy * (u1 * v2 - u2 * v1)) / det;
1193 if (OnLine(x1, y1, x2, y2, xc, yc) && OnLine(u1, v1, u2, v2, xc, yc))
1207bool ViewFEMesh::OnLine(
double x1,
double y1,
double x2,
double y2,
double u,
1212 1.0e-10 * std::max(std::abs(x1), std::max(std::abs(x2), std::abs(u)));
1214 1.0e-10 * std::max(std::abs(y1), std::max(std::abs(y2), std::abs(v)));
1215 if (xtol <= 0) xtol = 1.0e-10;
1216 if (ytol <= 0) ytol = 1.0e-10;
1219 double xc = 0, yc = 0;
1222 if ((std::abs(x1 - u) <= xtol && std::abs(y1 - v) <= ytol) ||
1223 (std::abs(x2 - u) <= xtol && std::abs(y2 - v) <= ytol)) {
1227 else if (std::abs(x1 - x2) <= xtol && std::abs(y1 - y2) <= ytol) {
1231 else if (std::abs(u - x1) + std::abs(v - y1) <
1232 std::abs(u - x2) + std::abs(v - y2)) {
1236 double dpar = ((u - x1) * (x2 - x1) + (v - y1) * (y2 - y1)) /
1237 ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
1243 }
else if (dpar > 1.0) {
1247 xc = x1 + dpar * (x2 - x1);
1248 yc = y1 + dpar * (y2 - y1);
1256 double dpar = ((u - x2) * (x1 - x2) + (v - y2) * (y1 - y2)) /
1257 ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
1263 }
else if (dpar > 1.0) {
1267 xc = x2 + dpar * (x1 - x2);
1268 yc = y2 + dpar * (y1 - y2);
1273 if (std::abs(u - xc) < xtol && std::abs(v - yc) < ytol)
return true;
1283bool ViewFEMesh::PlaneCut(
double x1,
double y1,
double z1,
double x2,
double y2,
1284 double z2, TMatrixD& xMat) {
1288 TMatrixD cutMat(3, 3);
1289 dataCut[0] = project[0][0];
1290 dataCut[1] = project[1][0];
1291 dataCut[2] = x1 - x2;
1292 dataCut[3] = project[0][1];
1293 dataCut[4] = project[1][1];
1294 dataCut[5] = y1 - y2;
1295 dataCut[6] = project[0][2];
1296 dataCut[7] = project[1][2];
1297 dataCut[8] = z1 - z2;
1298 cutMat.SetMatrixArray(dataCut.GetArray());
1303 (cutMat(1, 1) * cutMat(2, 2) - cutMat(1, 2) * cutMat(2, 1)) -
1305 (cutMat(1, 0) * cutMat(2, 2) - cutMat(1, 2) * cutMat(2, 0)) +
1307 (cutMat(1, 0) * cutMat(2, 1) - cutMat(1, 1) * cutMat(2, 0));
1310 if (cutDet == 0)
return false;
1313 TArrayD dataCoords(3);
1314 TMatrixD coordMat(3, 1);
1315 dataCoords[0] = x1 - project[2][0];
1316 dataCoords[1] = y1 - project[2][1];
1317 dataCoords[2] = z1 - project[2][2];
1318 coordMat.SetMatrixArray(dataCoords.GetArray());
1322 xMat = cutMat * coordMat;
1325 if (xMat(2, 0) < 0 || xMat(2, 0) > 1)
return false;
1333bool ViewFEMesh::PlaneCoords(
double x,
double y,
double z,
1334 const TMatrixD& projMat, TMatrixD& xMat) {
1337 TArrayD dataCoords(3);
1338 TMatrixD coordMat(3, 1);
1342 coordMat.SetMatrixArray(dataCoords.GetArray());
1343 xMat = projMat * coordMat;
1355bool ViewFEMesh::IsInPolygon(
double x,
double y, std::vector<double>& px,
1356 std::vector<double>& py,
bool& edge) {
1359 int pN = (int)px.size();
1362 if (pN < 2)
return false;
1364 if (pN == 2)
return OnLine(px[0], py[0], px[1], py[1], x, y);
1367 double px_min = px[0], py_min = py[0];
1368 double px_max = px[0], py_max = py[0];
1369 for (
int i = 0; i < pN; i++) {
1370 px_min = std::min(px_min, px[i]);
1371 py_min = std::min(py_min, py[i]);
1372 px_max = std::max(px_max, px[i]);
1373 py_max = std::max(py_max, py[i]);
1377 double xtol = 1.0e-10 * std::max(std::abs(px_min), std::abs(px_max));
1378 double ytol = 1.0e-10 * std::max(std::abs(py_min), std::abs(py_max));
1379 if (xtol <= 0) xtol = 1.0e-10;
1380 if (ytol <= 0) ytol = 1.0e-10;
1383 if (std::abs(px_max - px_min) < xtol) {
1384 edge = (y > (py_min - ytol) && y < (py_max + ytol) &&
1385 std::abs(px_max + px_min - 2 * x) < xtol);
1389 if (std::abs(py_max - py_min) < ytol) {
1390 edge = (x > (px_min - xtol) && x < (px_max + xtol) &&
1391 std::abs(py_max + py_min - 2 * y) < ytol);
1396 double xinf = px_min - std::abs(px_max - px_min);
1397 double yinf = py_min - std::abs(py_max - py_min);
1404 while (!done && niter < 100) {
1412 for (
int i = 0; (done && i < pN); i++) {
1415 if (OnLine(px[i % pN], py[i % pN], px[(i + 1) % pN], py[(i + 1) % pN], x,
1423 double xc = 0., yc = 0.;
1424 if (LinesCrossed(x, y, xinf, yinf, px[i % pN], py[i % pN],
1425 px[(i + 1) % pN], py[(i + 1) % pN], xc, yc))
1430 if (OnLine(x, y, xinf, yinf, px[i], py[i])) {
1433 xinf = px_min -
RndmUniform() * std::abs(px_max - xinf);
1434 yinf = py_min -
RndmUniform() * std::abs(py_max - yinf);
1445 std::cerr << className <<
"::IsInPolygon: unable to determine whether ("
1446 << x <<
", " << y <<
") is inside a polygon. Returning false.\n";
1451 return (ncross != 2 * (ncross / 2));
1460void ViewFEMesh::ClipToView(std::vector<double>& px, std::vector<double>& py,
1461 std::vector<double>& cx, std::vector<double>& cy) {
1464 int pN = (int)px.size();
1471 std::vector<double> vx;
1476 std::vector<double> vy;
1481 int vN = (int)vx.size();
1487 for (
int i = 0; i < pN; i++) {
1493 for (
int j = 0; j < vN; j++) {
1497 if (OnLine(vx[j % vN], vy[j % vN], vx[(j + 1) % vN], vy[(j + 1) % vN],
1501 cx.push_back(px[i]);
1502 cy.push_back(py[i]);
1510 if (OnLine(px[i % pN], py[i % pN], px[(i + 1) % pN], py[(i + 1) % pN],
1514 cx.push_back(vx[j]);
1515 cy.push_back(vy[j]);
1527 for (
int j = 0; j < vN; j++) {
1531 double xc = 0., yc = 0.;
1532 if (LinesCrossed(vx[j % vN], vy[j % vN], vx[(j + 1) % vN],
1533 vy[(j + 1) % vN], px[i % pN], py[i % pN],
1534 px[(i + 1) % pN], py[(i + 1) % pN], xc, yc)) {
1545 for (
int j = 0; j < vN; j++) {
1550 if (IsInPolygon(vx[j], vy[j], px, py, edge)) {
1553 cx.push_back(vx[j]);
1554 cy.push_back(vy[j]);
1559 for (
int i = 0; i < pN; i++) {
1564 if (IsInPolygon(px[i], py[i], vx, vy, edge)) {
1567 cx.push_back(px[i]);
1568 cy.push_back(py[i]);
DoubleAc sqrt(const DoubleAc &f)
std::vector< material > materials
std::vector< element > elements
std::vector< node > nodes
bool GetVoltageRange(double &vmin, double &vmax)
void SetXaxisTitle(const char *xtitle)
void SetCanvas(TCanvas *c)
void SetComponent(ComponentFieldMap *comp)
void SetYaxisTitle(const char *ytitle)
void SetPlane(double fx, double fy, double fz, double x0, double y0, double z0)
void SetXaxis(TGaxis *ax)
void SetYaxis(TGaxis *ay)
void SetDefaultProjection()
PlottingEngineRoot plottingEngine