/* * RayGenrator Klasse * v.01 * desc: generiert Wellenbild, inkl. Reflektionen * * Konstruktor Parameter: * myOrigin - Zentrum des Strahlenbildes * polygon - Begrenzung des Strahlenbildes * * Methoden * generateRay, intersectPt * * * * * * * * */ class RayGenerator { Vec Origin; // Zentrum des Strahlenbildes Polygon PolygonPoints; // Eckpunkte des begrenzenden Polygons int rayResolution = 6; // Startauflösung der Strahlen; Anzahl Strahlen = 360/value ArrayList intersectPoints; // alle ersten Schnittpunkte der Strahlen /* * CLASS KONSTRUKTOR */ RayGenerator(Vec myOrigin, Polygon myPolygon) { calculateRays(myOrigin, myPolygon); } /* * Methode: RayGenrator.calculateRays() * Desc: * * Params: * */ void calculateRays(Vec myOrigin, Polygon myPolygon) { intersectPoints = new ArrayList(); // alle ersten Schnittpunkte der Strahlen rayList = new ArrayList(); reflectedList = new ArrayList(); Origin = myOrigin; // Zentrum des Strahlenbildes PolygonPoints = myPolygon; // Eckpunkte des begrenzenden Polygons int rayCount; // Counter für for-Schleife //println("generating rays"); for (rayCount = 0;rayCount < 360; rayCount=rayCount+rayResolution)// radiale Strahlen berechnen und zeichnen { generateRay(rayCount); } } /* * Methode: RayGenrator.generateRay(float rayAngle) * Desc: Zeichnen eines Strahls inkl. Reflektion * * Params: * rayAngle - Winkel in dem der Strahl gezeichnet wird */ void generateRay(float rayAngle) { intersectPt intersectPtRayPolygon, intersectPtPolygonPolygon; int edgePtIndex1; // Index des erstens Kanteneckpunktes der Reflexionskante int edgePtIndex2; // Index des zweiten Kanteneckpunktes der Reflexionskante int edgePtIndex3; // Index des ersten Kanteneckpunktes der Kante, die vom reflektierten Strahl getroffen wird int edgePtIndex4; // Index des zweiten Kanteneckpunktes der Kante, die vom reflektierten Strahl getroffen wird Vec Pt1, Pt2; // Eckpunkte der Kante Vec MirrorLine; float rayT = 1; // Länge des Vectors float rayX = cos(rayAngle * PI/180) * rayT; // x-Komponente des Vektors float rayY = sin(rayAngle * PI/180) * rayT; // y-Komponente des Vektors Vec ray = new Vec(rayX, rayY); // Richtungsvektor des Strahls Vec reflected; // Richtungsvektor des reflektierten Strahls intersectPtRayPolygon = getIntersect(ray, Origin); // finde Position und Index des erstens Punktes dessen Kante sich mit dem Strahl schneidet edgePtIndex1 = intersectPtRayPolygon.getIndex(); if (edgePtIndex1 == PolygonPoints.polyPoints.size()-1) { edgePtIndex2=0; } // finde den folgenden Kantenpunkt; bei letzter Kante mit erstem Polygonpunkt verbinden else { edgePtIndex2 = edgePtIndex1+1; } Vec pt1 = new Vec(PolygonPoints.getPt(edgePtIndex1)); // Kanteneckpunkte holen Vec pt2 = new Vec(PolygonPoints.getPt(edgePtIndex2)); ArrayList rayLine = new ArrayList(); // Speichere gefundenen Punkt in ArrayList rayLine.add(Origin); rayLine.add(intersectPtRayPolygon.getPos()); rayList.add(rayLine); Vec edge = new Vec( pt2.subVec( pt1 )); // Zeichne Reflektion an Kante mit erstem Eckpunkt intersectIndex MirrorLine = edge.makeUnit().rotateV90(); reflected = ray.reflect(MirrorLine); // Strahl an Spiegelachse spiegeln // finde Index des erstens Punktes dessen Kante sich mit dem Strahl schneidet intersectPtPolygonPolygon = getIntersect(reflected, intersectPtRayPolygon.getPos()); ArrayList reflectedLine = new ArrayList(); // Speichere gefundenen Punkt in ArrayList //if (intersectPtPolygonPolygon != new Vec(0,0)) //{ reflectedLine.add(intersectPtRayPolygon.getPos()); // Startpunkt des reflektierten Strahls reflectedLine.add(intersectPtPolygonPolygon.getPos()); // Endpunkt des reflektierten Strahls reflectedList.add(reflectedLine); // Liste mi allen reflektierten Strahlen //} } /* * Methode: RayGenrator.getIntersect(Vec vRay, Vec rayStart) * Desc: sucht Schnittpunkte mit Polygonkante und überprüft welcher korrekt ist * * Params: * vRay - Richtung des Vektors * rayStart - Koordinaten des Punktes von dem der Strahl gezeichnet werden soll * (kann Strahlenzentrum oder Punkt auf Polygonkante sein) * */ intersectPt getIntersect(Vec vRay, Vec rayStart) { Vec posIntersectPt = null; // Koordinaten des Schnittpunkts intersectPt intersectPointAndId; // Schnittpunkt und Id des ersten Punkts auf der Kante boolean intersectfound = false; // Abbruchbedingung für while-Schleife Vec currPt, nextPt; // erster und zweiter Eckpunkt der Kante int index = 0; // index des ersten Punkts der Kante auf der der Schnittpunkt gefunden wurde int i = 0; // Counter für while-Schleife float p1x, p1y, p2x, p2y, p3x, p3y, r1x, r1y, r2x, r2y,t2,intersectX, intersectY; int n = PolygonPoints.polyPoints.size(); while (!intersectfound && (i < n)) { int k = (i+1)% n; currPt = PolygonPoints.getPt(i); nextPt = PolygonPoints.getPt(k); p1x = currPt.getX(); // Punkte des Vectors p1y = currPt.getY(); p2x = nextPt.getX(); p2y = nextPt.getY(); r1x = rayStart.getX(); // Punkte des Rays r1y = rayStart.getY(); r2x = rayStart.getX() + vRay.getX(); r2y = rayStart.getY() + vRay.getY(); t2 = ( (r1y - p1y)*(p2x-p1x) - (r1x-p1x)*(p2y-p1y) ) / ( (r2x-r1x)*(p2y-p1y) - (r2y-r1y)*(p2x-p1x) ); intersectX = r1x + t2 * (r2x - r1x); intersectY = r1y + t2 * (r2y - r1y); posIntersectPt = new Vec(intersectX, intersectY); // Überprüfung ob der Schnittpunkt zwischen zwei Eckpunkten liegt // Auflistung aller Kombinationsmöglichkeiten des IntersectPoint zu den XY Werten der Polygonkante boolean case1 = ((nextPt.getX() <= intersectX) && (intersectX <= currPt.getX())) && ((nextPt.getY() <= intersectY) && (intersectY <= currPt.getY())); boolean case2 = ((nextPt.getX() <= intersectX) && (intersectX <= currPt.getX())) && ((currPt.getY() <= intersectY) && (intersectY <= nextPt.getY())); boolean case3 = ((currPt.getX() <= intersectX) && (intersectX <= nextPt.getX())) && ((currPt.getY() <= intersectY) && (intersectY <= nextPt.getY())); boolean case4 = ((currPt.getX() <= intersectX) && (intersectX <= nextPt.getX())) && ((nextPt.getY() <= intersectY) && (intersectY <= currPt.getY())); boolean tester = false; for (int j=0; j < PolygonPoints.polyPoints.size(); j++) { Vec Test = (Vec) PolygonPoints.polyPoints.get(j); if (posIntersectPt == Test) { tester = true; } } if ( (case1 || case2 || case3 || case4) && (t2 > 0) ) { intersectfound = true; index = i; stroke(cHighlight1); ellipse(posIntersectPt.getX(),posIntersectPt.getY(),1,1); } i++; } intersectPointAndId = new intersectPt(posIntersectPt ,index); return intersectPointAndId; } /* * Methode: RayGenrator.raysDraw() * Desc: zeichnet das Strahlenbild * * Params: - */ void raysDraw() { int i; // counter für for-Schleife for (i=0; i <= reflectedList.size()-1; i++) // reflected zeichnen { ArrayList currLine = (ArrayList) reflectedList.get(i); Vec startPt = (Vec) currLine.get(0); Vec endPt = (Vec) currLine.get(1); stroke(cNormal2); // zeichne Strahl Strahlenquelle-Polygonrand line(startPt.getX(), startPt.getY(), endPt.getX(), endPt.getY()); } for (i=0; i <= rayList.size()-1; i++) // rays zeichnen { ArrayList currLine = (ArrayList) rayList.get(i); Vec startPt = (Vec) currLine.get(0); Vec endPt = (Vec) currLine.get(1); stroke(cNormal1); // zeichne Strahl Strahlenquelle-Polygonrand line(startPt.getX(), startPt.getY(), endPt.getX(), endPt.getY()); } } /* * Methode: RayGenrator.setRayResolution(int value) * Desc: ändert die Anzahl der Strahlen * * Params: * value - neue Auflösung der Strahlen; Anzahl Strahlen = 360/value */ void setRayResolution(int value) { rayResolution = value; } }