ΠŸΠΎΠΌΠΎΡ‰ΡŒ Π² написании студСнчСских Ρ€Π°Π±ΠΎΡ‚
АнтистрСссовый сСрвис

ΠžΡ‚Ρ€ΠΈΡΠΎΠ²ΠΊΠ° сцСны Β«ΠžΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΠ΅ΡΡ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈΒ» Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΉ трассировки Π»ΡƒΡ‡Π΅ΠΉ

ΠšΡƒΡ€ΡΠΎΠ²Π°ΡΠŸΠΎΠΌΠΎΡ‰ΡŒ Π² Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠΈΠ£Π·Π½Π°Ρ‚ΡŒ ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒΠΌΠΎΠ΅ΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹

ListOfObjects. addElement (new Sphere (currentSurface, new WorkVector ((float) i*(float) 1.0βˆ’9, (float) — 5*(float) Math. sqrt ((float) i)+7, (float) — j*j*(float) 1.00+(float) 6), (float) 0.8)); WorkVector v = new WorkVector (-ray.finalRay.x, — ray.finalRay.y, — ray.finalRay.z); // Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π²Π΅ΠΊΡ‚ΠΎΡ€Π° — ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ направлСния Π»ΡƒΡ‡Π°. Public Color Shade (WorkVector p, WorkVector n, WorkVector v… Π§ΠΈΡ‚Π°Ρ‚ΡŒ Π΅Ρ‰Ρ‘ >

ΠžΡ‚Ρ€ΠΈΡΠΎΠ²ΠΊΠ° сцСны Β«ΠžΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΠ΅ΡΡ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈΒ» Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΉ трассировки Π»ΡƒΡ‡Π΅ΠΉ (Ρ€Π΅Ρ„Π΅Ρ€Π°Ρ‚, курсовая, Π΄ΠΈΠΏΠ»ΠΎΠΌ, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Π°Ρ)

ΠšΡƒΡ€ΡΠΎΠ²Π°Ρ Ρ€Π°Π±ΠΎΡ‚Π°

Π½Π° Ρ‚Π΅ΠΌΡƒ:

"ΠžΡ‚Ρ€ΠΈΡΠΎΠ²ΠΊΠ° сцСны «ΠžΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΠ΅ΡΡ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ» Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΉ трассировки Π»ΡƒΡ‡Π΅ΠΉ"

Π•ΠΊΠ°Ρ‚Π΅Ρ€ΠΈΠ½Π±ΡƒΡ€Π³ 2011 Π³.

Алгоритм Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

1) Π—Π°Ρ€Π°Π½Π΅Π΅ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π·Π°Π΄Π°Π½Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ ΠΈΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ свСта, Ρ‚ΠΈΠΏ повСрхности ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΎΠΊΠ½Π° для отобраТСния изобраТСния, Ρ†Π²Π΅Ρ‚ Ρ„ΠΎΠ½Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΎΠ±Π·ΠΎΡ€Π°;

2) Π—Π°Ρ‚Π΅ΠΌ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ пиксСля изобраТСния рассчитываСм Ρ†Π²Π΅Ρ‚, для этого направляСм Π»ΡƒΡ‡ΠΈ;

3) Если Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ Π»ΡƒΡ‡ Π½Π΅ ΠΏΠ΅Ρ€Π΅ΡΠ΅ΠΊΠ°Π΅Ρ‚ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° сцСны, Ρ‚ΠΎ Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹ΠΉ пиксСль Π² Ρ†Π²Π΅Ρ‚ Ρ„ΠΎΠ½Π°.

4) Если ΠΆΠ΅ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ Π»ΡƒΡ‡ пСрСсСкаСт ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ сцСны, Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π°Π΅ΠΌΡΡ ΠΊ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ класса Ray Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΌΡƒ Ρ†Π²Π΅Ρ‚ Π² Ρ‚ΠΎΡ‡ΠΊΠ΅ пСрСсСчСния. Он Π² ΡΠ²ΠΎΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ обращаСтся ΠΊ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠΌΡƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ класса Sphere, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Ρ‚ΠΎΡ‡ΠΊΠΈ пСрСсСчСния Π»ΡƒΡ‡Π° с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π΄Π»ΠΈΠ½Ρƒ Π»ΡƒΡ‡Π° (Π²Π΅ΠΊΡ‚ΠΎΡ€Π°) Π΄ΠΎ Ρ‚ΠΎΡ‡ΠΊΠΈ пСрСсСчСния с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ Π²Π΅ΠΊΡ‚ΠΎΡ€ Π½ΠΎΡ€ΠΌΠ°Π»ΠΈ ΠΊ ΠΏΠΎΠ²Π΅Ρ€Ρ…ности Π² Ρ‚ΠΎΡ‡ΠΊΠ΅ пСрСсСчСния.

5) ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ всС Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹Π΅ Π²Ρ‹ΡˆΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π² ΠΌΠ΅Ρ‚ΠΎΠ΄ класса Surface, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ рассчитываСт Ρ†Π²Π΅Ρ‚ Π² Π΄Π°Π½Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅. Π’ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΠΈ ΠΎΡ‚ ΡΠ²ΠΎΠΉΡΡ‚Π² ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π° пСрСсСчСнного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ Π·Π°Ρ‚Π΅Π½Π΅Π½Π½ΠΎΡΡ‚ΡŒ, ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, ΠΏΡ€Π΅Π»ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ Π² Π΄Π°Π½Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅. ΠŸΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Π΄Π²ΡƒΡ… послСдних гСнСрируСтся Π½ΠΎΠ²Ρ‹ΠΉ Π»ΡƒΡ‡, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ трассируСтся (Ρ‚.Π΅. ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ Π·Π°Π½ΠΎΠ²ΠΎ ΠΏΡƒΠ½ΠΊΡ‚Ρ‹ 3−5 Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° (рСкурсия)). ΠŸΡ€ΠΈ трассировкС этого Π»ΡƒΡ‡Π° ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ†Π²Π΅Ρ‚ Π² Π΄Π°Π½Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ модифицируСтся ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ коэффициСнтов ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ся Π² Π³Π»Π°Π²Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ отрисовки.

Π‘Π»ΠΎΠΊ-схСма ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° трассировка Ρ‚Π΅Π½ΡŒ освСщСниС

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π½Π°Π΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ Π±Ρ‹Π»ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ поставлСнныС трСбования: Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° трассировка Π»ΡƒΡ‡Π΅ΠΉ с ΠΏΡ€ΠΎΡΡ‡Π΅Ρ‚ΠΎΠΌ Ρ‚Π΅Π½Π΅ΠΉ, освСщСния, отраТСния, прСломлСния Π»ΡƒΡ‡Π΅ΠΉ, Ρ‡Ρ‚ΠΎ являСтся нСсомнСнным достоинством ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π’Π°ΠΊΠΆΠ΅ Π·Π°Π΄Π°Π½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ — сфСра. НСдостатком ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΡΡ‡ΠΈΡ‚Π°ΡŽ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Π½Ρ‹ Ρ‚Π°ΠΊΠΈΠ΅ источники свСта, ΠΊΠ°ΠΊ свСт ΠΎΠΊΡ€ΡƒΠΆΠ°ΡŽΡ‰Π΅ΠΉ срСды ΠΈ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ свСт.

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 1

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 2

Листинг Light. java

package objects;

/**

*

* @author АлСксСй

*/

// Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ свСта

public class Light {

public WorkVector lightvec; // позиция истоника свСта

public float lightred, lightgreen, lightblue; // Ρ†Π²Π΅Ρ‚ источника свСта

public Light (WorkVector v, float r, float g, float b) {

lightvec = v;

lightred = r;

lightgreen = g;

lightblue = b;

}

}

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 3

Листинг Ray. java

package objects;

import java.awt. Color;

import java.util. Vector;

/**

*

* @author АлСксСй

*/

// Π›ΡƒΡ‡

public class Ray {

float max_distance = Float. MAX_VALUE; // максимальная Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для currentDistance Π»ΡƒΡ‡Π°

WorkVector initRay; // Π½Π°Ρ‡Π°Π»ΠΎ Π»ΡƒΡ‡Π°

WorkVector finalRay; // Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π»ΡƒΡ‡Π°

float currentDistance; // Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ расстояниС Π΄ΠΎ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°

Sphere object; // ΠžΠ±ΡŒΠ΅ΠΊΡ‚, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ столкновСниС Π»ΡƒΡ‡Π°

public Ray (WorkVector eye, WorkVector dir) {

initRay = new WorkVector (eye);

finalRay = WorkVector. normalize (dir);

}

public boolean trace (Vector objects) {

currentDistance = max_distance;

object = null;

for (int i = 0; i < objects. size (); i++) {

Sphere object = (Sphere) objects. elementAt (i);

object.intersection (this); // ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° пСрСсСчСния с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ

}

return (object≠ null); // Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ true Ссли Π±Ρ‹Π»ΠΎ пСрСсСчСниС

}

public final Color Shade (Vector lights, Vector objects, Color bgnd) {

return object. Shade (this, lights, objects, bgnd);

}

}

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 4

Листинг Sphere. java

package objects;

import java.awt. Color;

import java.util. Vector;

/**

*

* @author АлСксСй

*/

// Π‘Ρ„Π΅Ρ€Π°

public class Sphere {

Surface surface; // Ρ‚ΠΈΠΏ повСрхности

WorkVector center; // ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ сфСры

float radius; // радиус сфСры

public Sphere (Surface s, WorkVector c, float r) {

surface = s;

center = c;

radius = r;

}

public boolean intersection (Ray ray)

public Color Shade (Ray ray, Vector lights, Vector objects, Color bgnd) {

// вызываСтся, Ссли Π±Ρ‹Π»Π° Π½Π°ΠΉΠ΄Π΅Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° пСрСсСчСния ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π° ΠΈ Π»ΡƒΡ‡Π°

// Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π»ΡƒΡ‡Π° увСличиваСтся Π½Π° Ρ€Π°ΡΡΡ‚ояниС Π΄ΠΎ Ρ‚ΠΎΡ‡ΠΊΠΈ пСрСсСчСния

float px = ray.initRay.x + ray. currentDistance*ray.finalRay.x;

float py = ray.initRay.y + ray. currentDistance*ray.finalRay.y;

float pz = ray.initRay.z + ray. currentDistance*ray.finalRay.z;

WorkVector p = new WorkVector (px, py, pz); // Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΡ‡ΠΊΠΈ пСрСсСчСния Π»ΡƒΡ‡Π° ΠΈ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°

WorkVector v = new WorkVector (-ray.finalRay.x, — ray.finalRay.y, — ray.finalRay.z); // Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π²Π΅ΠΊΡ‚ΠΎΡ€Π° — ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ направлСния Π»ΡƒΡ‡Π°

WorkVector n = new WorkVector ((px — center. x), (py — center. y), (pz — center. z)); // находится Π²Π΅ΠΊΡ‚ΠΎΡ€, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅ повСрхности

n.normalize (); // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒ

return surface. Shade (p, n, v, lights, objects, bgnd); // возвращяСстя Ρ†Π²Π΅Ρ‚ Π² Π΄Π°Π½Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅

}

}

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 5

Листинг Surface. java

package objects;

import java.awt. Color;

import java.util. Vector;

/**

*

* @author АлСксСй

*/

public class Surface {

public float ir, ig, ib; // Ρ†Π²Π΅Ρ‚ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°

public float kRasseivania, kOtragenia, ns; // константы для освСщСния ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°

public float kt, kr; // коэффициСнты ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°

private float TINY = 0.001f;

private float I255 = 0.39 2156f;

private WorkVector luch;

public Surface (float rval, float gval, float bval, float d,

float s, float n, float r, float t) {

ir = rval; ig = gval; ib = bval; // Π·Π°Π΄Π°Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π° повСрхности

kRasseivania = d; // Ρ€Π°ΡΡΠ΅ΠΈΠ²Π°ΡŽΡ‰Π°Ρ ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰Π°Ρ повСрхности

kOtragenia = s; // ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‰Π°Ρ ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰Π°Ρ повСрхности

ns = n;

kr = r*I255;

kt = t*I255;

}

public Color Shade (WorkVector p, WorkVector n, WorkVector v, Vector lights, Vector objects, Color bgnd) // Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ Ρ†Π²Π΅Ρ‚ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π° Π² Ρ‚ΠΎΡ‡ΠΊΠ΅

// Ρ‚ΠΎΡ‡ΠΊΠ° пСрСсСчСния (p)

// Π½ΠΎΡ€ΠΌΠ°Π»ΡŒ Π² Ρ‚ΠΎΡ‡ΠΊΠ΅ пСрСсСчСния (n)

// Π²Π΅ΠΊΡ‚ΠΎΡ€ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ Π² Ρ‚ΠΎΡ‡ΠΊΡƒ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΈΡˆΠ΅Π» Π»ΡƒΡ‡ΡŒ (v)

{

float r = 0; // обнуляСм

float g = 0;

float b = 0;

for (int i = 0; i < lights. size (); i++) { // Ρ†ΠΈΠΊΠ», Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ расчитываСтся ΠΎΡΠ²Π΅Ρ‰Π΅Π½Π½ΠΎΡΡ‚ΡŒ

Light light = (Light) lights. elementAt (i); // взятиС Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ истчоника освСщСния

luch = new WorkVector (light.lightvec.sub (p)); // Π·Π°Π΄Π°Π΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ luch ΠΊΠ°ΠΊ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΎΡ‚ ΠΈΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠ° освСщСния Π΄ΠΎ Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°

luch.normalize (); // Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ luch Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π²Π΅ΠΊΡ‚ΠΎΡ€ направлСния ΠΎΡ‚ ΠΈΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠ° освСщСния ΠΊ Ρ‚ΠΎΡ‡ΠΊΠ΅ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°

// Π—ΠΠ’Π•ΠΠ•ΠΠΠžΠ‘Π’Π¬

WorkVector poffset = p. add (luch.mul (TINY)); // ΠΊ ΠΎΡΠ½ΠΎΠ²Π°Π½ΠΈΡŽ Π½ΠΎΠ²ΠΎΠ³ΠΎ Π»ΡƒΡ‡Π° добавляСтся ΠΎΡ‡Π΅Π½ΡŒ мальСнький Π²Π΅ΠΊΡ‚ΠΎΡ€ luch Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅ Π½Π΅ ΠΏΠ΅Ρ€Π΅ΡΠ΅Ρ‡ΡŒ сам сСбя

Ray shadowRay = new Ray (poffset, luch); // созданиС Π»ΡƒΡ‡Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° Π·Π°Ρ‚Π΅Π½Π΅Π½Π½ΠΎΡΡ‚ΡŒ

if (shadowRay.trace (objects)) // Π² ΡΠ»ΡƒΡ‡Π°Π΅ пСоСсСчСния ΠΊΠ°ΠΊΠΎΠ³ΠΎ Π»ΠΈΠ±ΠΎ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°

continue; // ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ источнику освСщСния

float lambert = WorkVector. dot (n, luch); // Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ коэффициСнта освСщСнности Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΠΈ ΠΎΡ‚ Π½ΠΎΡ€ΠΌΠ°Π»ΠΈ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π° Π² Π΄Π°Π½Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅ ΠΈ Π½Π°ΠΏΡ€Π°Π»Π΅Π½ΠΈΡ источника свСта

if (lambert > 0) {

if (kRasseivania > 0) {

float diffuse = kRasseivania*lambert;

r += diffuse*ir*light.lightred;

g += diffuse*ig*light.lightgreen;

b += diffuse*ib*light.lightblue;

}

if (kOtragenia > 0) {

lambert *= 2;

float spec = v. dot (lambert*n.x — luch. x, lambert*n.y — luch. y, lambert*n.z — luch. z);

if (spec > 0) {

spec = kOtragenia*((float) Math. pow ((double) spec, (double) ns));

r += spec*light.lightred;

g += spec*light.lightgreen;

b += spec*light.lightblue;

}

}

}

}

// ΠžΠ’Π ΠΠ–Π•ΠΠ˜Π•

if (kr > 0) { // Ссли коэффициСнт отраТСния большС нуля, Ρ‚ΠΎ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Ρ€Π°ΠΆΠ°Ρ‚ΡŒ

float t = v. dot (n); // ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° скалярного произвСдСния Π²Π΅ΠΊΡ‚ΠΎΡ€Π° Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ источника Π»ΡƒΡ‡Π° ΠΈ Π½ΠΎΡ€ΠΌΠ°Π»ΠΈ повСрхности Π² Π΄Π°Π½Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅

if (t > 0) {

t *= 2;

WorkVector reflect = new WorkVector (n.mul (t).sub (v));

WorkVector poffset = new WorkVector (p.add (reflect.mul (TINY)));

Ray reflectedRay = new Ray (poffset, reflect);

if (reflectedRay.trace (objects)) {

Color rcolor = reflectedRay. Shade (lights, objects, bgnd);

r += kr*rcolor.getRed ();

g += kr*rcolor.getGreen ();

b += kr*rcolor.getBlue ();

} else {

r += kr*bgnd.getRed ();

g += kr*bgnd.getGreen ();

b += kr*bgnd.getBlue ();

}

}

}

// ΠŸΠ Π˜Π›ΠžΠœΠ›Π•ΠΠ˜Π•

if (kt > 0) {

WorkVector tr;

WorkVector incident = v. add (p);

float eta = (float) 0.7;

float c1 = incident. mul (-1).dot (n);

float c2;

c2 = 1 — eta*eta*(1-c1*c1);

if (c2 > 0.0) {

c2 = (float) (Math.sqrt (c2));

float maae = (eta*c1 — c2);

tr = incident. mul (eta).add (n.mul (maae));

tr.normalize ();

WorkVector poffset = p. add (n.mul (-TINY));

Ray reflectedRay = new Ray (poffset, tr);

if (reflectedRay.trace (objects)) {

Color rcolor = reflectedRay. Shade (lights, objects, bgnd);

r += kt*rcolor.getRed ();

g += kt*rcolor.getGreen ();

b += kt*rcolor.getBlue ();

} else {

r += kt*bgnd.getRed ();

g += kt*bgnd.getGreen ();

b += kt*bgnd.getBlue ();

}

}

}

// Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Π²Ρ‹Ρ…ΠΎΠ΄ Π·Π° Π³Ρ€Π°Π½ΠΈΡ†Ρ‹

r = (r > 1f)? 1f: r;

r = (r < 0f)? 0f: r;

g = (g > 1f)? 1f: g;

g = (g < 0f)? 0f: g;

b = (b > 1f)? 1f: b;

b = (b < 0f)? 0f: b;

return new Color (r, g, b); // Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ Ρ†Π²Π΅Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠΈ

}

}

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 6

Листинг WorkVector. java

package objects;

/**

*

* @author АлСксСй

*/

public class WorkVector {

public float x, y, z; // ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π²Π΅ΠΊΡ‚ΠΎΡ€Π°

public WorkVector () {}

public WorkVector (float X, float Y, float Z) {

x = X;

y = Y;

z = Z;

}

public WorkVector (WorkVector v) {

x = v. x;

y = v. y;

z = v. z;

}

// ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹

public float dot (WorkVector v) { // скалярноС ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅

return (x*v.x + y*v.y + z*v.z);

}

public float dot (float Bx, float By, float Bz) {

return (x*Bx + y*By + z*Bz);

}

public static float dot (WorkVector A, WorkVector B) {

return (A.x*B.x + A. y*B.y + A. z*B.z);

}

public WorkVector add (WorkVector A) { // Π’Π΅ΠΊΡ‚ΠΎΡ€ слоТСния

return new WorkVector (x+A.x, y+A.y, z+A.z);

}

public WorkVector sub (WorkVector A) { // Π’Π΅ΠΊΡ‚ΠΎΡ€ разности

return new WorkVector (x-A.x, y-A.y, z-A.z);

}

public WorkVector mul (float A) { // Π’Π΅ΠΊΡ‚ΠΎΡ€, ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ Π½Π° Ρ‡ΠΈΡΠ»ΠΎ

return new WorkVector (x*A, y*A, z*A);

}

public WorkVector set (WorkVector A) { // Π—Π°Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚

return new WorkVector (A.x, A. y, A. z);

}

public WorkVector set (float Ax, float Ay, float Az) {

return new WorkVector (Ax, Ay, Az);

}

public WorkVector cross (WorkVector B) {

return new WorkVector (y*B.z — z*B.y, z*B.x — x*B.z, x*B.y — y*B.x);

}

public WorkVector cross (float Bx, float By, float Bz) {

return new WorkVector (y*Bz — z*By, z*Bx — x*Bz, x*By — y*Bx);

}

public WorkVector cross (WorkVector A, WorkVector B) {

return new WorkVector (A.y*B.z — A. z*B.y, A. z*B.x — A. x*B.z, A. x*B.y — A. y*B.x);

}

public float length () { // НахоТдСниС Π΄Π»ΠΈΠ½Ρ‹ Π²Π΅ΠΊΡ‚ΠΎΡ€Π°

return (float) Math. sqrt (x*x + y*y + z*z);

}

public float length (WorkVector A) {

return (float) Math. sqrt (A.x*A.x + A. y*A.y + A. z*A.z);

}

public void normalize () { // нормализация Π²Π΅ΠΊΡ‚ΠΎΡ€Π°

float t = x*x + y*y + z*z;

if (t≠ 0 && t≠ 1) t = (float) (1 / Math. sqrt (t));

x *= t;

y *= t;

z *= t;

}

public static WorkVector normalize (WorkVector A) {

float t = A. x*A.x + A. y*A.y + A. z*A.z;

if (t≠ 0 && t≠ 1) t = (float) (1 / Math. sqrt (t));

return new WorkVector (A.x*t, A. y*t, A. z*t);

}

}

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 7

Листинг Main. java

package ray_tracing;

import objects.*;

import java.awt. Color;

import java.awt. Frame;

import java.awt. Graphics;

import java.awt. Image;

import java.awt.event. WindowAdapter;

import java.awt.event. WindowEvent;

import java.util. Vector;

/**

*

* @author АлСксСй

*/

public class Main {

final static int kol_vo = 600;

static Image screen;

static Graphics gc;

static Vector listOfObjects;

static Vector listOfLights;

static Surface currentSurface;

static WorkVector eye, lookat, up; // Π²Π΅ΠΊΡ‚ΠΎΡ€Ρ‹ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ для задания ΠΏΡ€ΠΎΠ΅ΠΊΡ†ΠΈΠΈ

static float angle = 40; // ΡƒΠ³ΠΎΠ» ΠΎΠ±Π·ΠΎΡ€Π°

static Color background = new Color (0,0,0); // Ρ†Π²Π΅Ρ‚ Ρ„ΠΎΠ½Π°

static int width=640, height=480;

static Frame frame = new Frame («Raytracing»); // созданиС Ρ„Ρ€Π΅ΠΉΠΌΠ° для отобраТСния

public static void main (String[] args) {

frame.setSize (width, height);

frame.setLocationRelativeTo (null);

frame.setVisible (true);

screen = frame. createImage (width, height);

gc = screen. getGraphics ();

gc.setColor (frame.getBackground ());

gc.fillRect (0, 0, width, height);

frame.addWindowListener (new WindowAdapter () {

@Override

public void windowClosing (WindowEvent e) {

System.exit (0);

}

});

// Π·Π°Π΄Π°Π½ΠΈΠ΅ списков ΠΎΠ±ΡŒΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ ΠΈΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΎΠ² освСщСния

listOfObjects = new Vector (kol_vo, kol_vo);

listOfLights = new Vector (kol_vo, kol_vo);

// Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ источника освСщСния

listOfLights.addElement (new Light (new WorkVector ((float) 2, (float) 2, (float) 1), 1, 1, 1));

listOfLights.addElement (new Light (new WorkVector ((float) — 3, (float) 5, (float) 3), 1, 1, 1));

// добавлСния сфСр Π½Π° ΡΡ†Π΅Π½Ρƒ

for (int i=0; i<40; i++)

for (int j=0; j<10; j++)

{

// Π—Π°Π΄Π°Π½ΠΈΠ΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π° для ΠΎΠ±ΡŒΠ΅ΠΊΡ‚ΠΎΠ²

currentSurface = new Surface (i*j*0.02f, 0.7f, i*j*0.01f, 0.4f, 0.4f, 10.0f, 0f, 0f);

// Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°

listOfObjects.addElement (new Sphere (currentSurface, new WorkVector ((float) i*(float) 1.0−9, (float) — 5*(float) Math. sqrt ((float) i)+7, (float) — j*j*(float) 1.00+(float) 6), (float) 0.8));

}

currentSurface = new Surface (0.6f, 0.6f, 0.4f, 0.2f, 0.4f, 10.0f, 1.0f, 0.2f);

listOfObjects.addElement (new Sphere (currentSurface, new WorkVector ((float) 20, (float) 0, (float) — 40), (float) 15));

// Π—Π°Π΄Π°Π½ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… для Ρ€Π΅Π½Π΄Π΅Ρ€Π°

eye = new WorkVector (5, 0, 40); // ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΎΠ±Π·ΠΎΡ€Π°

lookat = new WorkVector (0, 0, 0); // ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Ρ‚ΠΎΡ‡ΠΊΠΈ направлСния взгляда

up = new WorkVector (0, 1, 0); // Π²Π΅ΠΊΡ‚ΠΎΡ€ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π²Π΅Ρ€Ρ…

Graphics g = frame. getGraphics ();

WorkVector Eye, Du, Dv, Vp;

WorkVector look = new WorkVector (lookat.x — eye. x, lookat. y — eye. y, lookat. z — eye. z);

float fl = (float) (width / (2*Math.tan ((0.5*angle)*Math.PI/180)));

Eye = eye;

Du = WorkVector. normalize (look.cross (up)); // Π²Π΅ΠΊΡ‚ΠΎΡ€ ΡΠ²Π»ΡΡŽΡ‰ΠΈΠΉΡΡ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΎΠΌ для Ρ€Π΅Π½Π΄Π΅Ρ€Π° «ΠΏΠΎ ΠΎΡΠΈ Ρ…»

Dv = WorkVector. normalize (look.cross (Du)); // Π²Π΅ΠΊΡ‚ΠΎΡ€ ΡΠ²Π»ΡΡŽΡ‰ΠΈΠΉΡΡ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΎΠΌ для Ρ€Π΅Π½Π΄Π΅Ρ€Π° «ΠΏΠΎ ΠΎΡΠΈ y»

Vp = WorkVector. normalize (look); // Π²Π΅ΠΊΡ‚ΠΎΡ€ ΡΠ²Π»ΡΡŽΡ‰ΠΈΠΉΡΡ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΎΠΌ для Ρ€Π΅Π½Π΄Π΅Ρ€Π° «ΠΏΠΎ ΠΎΡΠΈ z»

Vp = (Vp.mul (fl)).sub ((((Du.mul (width)).add (Dv.mul (height))).mul (0.5f)));

for (int j = 0; j < height; j++) {

for (int i = 0; i < width; i++) {

WorkVector dir = new WorkVector (((Du.mul (i)).add (Dv.mul (j)).add (Vp))); // Π·Π°Π΄Π°Π½ΠΈΠ΅ Ρ‚ΠΎΡ‡ΠΊΠΈ Π½Π°Ρ‡Π°Π»Π° Π»ΡƒΡ‡Π°

Ray ray = new Ray (Eye, dir); // Π·Π°Π΄Π°Π½ΠΈΠ΅ Π²Π΅ΠΊΡ‚ΠΎΡ€Π° направлСния Π»ΡƒΡ‡Π°

if (ray.trace (listOfObjects)) { // Ссли Π±Ρ‹Π»ΠΎ Π½Π°ΠΉΠ΄Π΅Π½ΠΎ пСрСсСчСниС с ΠΎΠ±Π΅ΠΊΡ‚ΠΎΠΌ

gc.setColor (ray. Shade (listOfLights, listOfObjects, background)); // Ρ‚ΠΎ Ρ‚ΠΎΡ‡ΠΊΠ° ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ расчитываСмый Ρ†Π²Π΅Ρ‚

} else {

gc.setColor (background); // Если Π½Π΅ Π±Ρ‹Π»ΠΎ пСрСсСчСния с ΠΎΠ±ΡŒΠ΅ΠΊΡ‚Π°ΠΌΠΈ Ρ‚ΠΎ Ρ‚ΠΎΡ‡ΠΊΠ° ΠΈΠΌΠ΅Π΅Ρ‚ Ρ†Π²Π΅Ρ‚ Ρ„ΠΎΠ½Π°

}

gc.drawLine (i, j, i, j); // рисованиС Ρ‚ΠΎΡ‡ΠΊΠΈ Π½Π° Π±ΡƒΡ„Π΅Ρ€Π½ΠΎΠΌ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ

}

}

g.drawImage (screen, 0, 0, frame); // отрисовка всСго изобраТСния Π½Π° ΡΠΊΡ€Π°Π½Π΅

}

}

ΠŸΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ вСсь тСкст
Π—Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΡƒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ