//############################################################################
//
// LaserBoy !!!
//
// by James Lehman
// Extra Stimulus Inc.
// james@akrobiz.com
//
// began: October 2003
//
// Copyright 2003 to 2025 James Lehman.
// This source is distributed under the terms of the GNU General Public License.
//
// LaserBoy_real_segment.cpp is part of LaserBoy.
//
// LaserBoy is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// LaserBoy is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with LaserBoy. If not, see .
//
//############################################################################
#include "LaserBoy_FLTK_GUI.hpp"
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_real_vertex from,
LaserBoy_real_vertex to
) // 3D line function
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{ // 3D line constructor
int steps = linear_steps(to, from, ( (to.is_lit())
? (p_space->lit_delta_max)
: (p_space->blank_delta_max)
)
);
if(steps)
{
LaserBoy_3D_double _to (to),
_from (from),
difference (_to - _from),
delta (difference / steps);
//----------------------------------------------------------------
for(int i = 1; i < steps; i++)
push_back(LaserBoy_real_vertex( LaserBoy_3D_double(_from + (delta * i)),
(LaserBoy_color)to,
to.k,
to.c
)
);
//----------------------------------------------------------------
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_real_vertex from,
LaserBoy_real_vertex to,
const u_int& max_d
) // 3D line function
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{ // 3D line constructor
int steps = linear_steps(to, from, max_d);
if(steps)
{
LaserBoy_3D_double _to (to),
_from (from),
difference (_to - _from),
delta (difference / steps);
//----------------------------------------------------------------
for(int i = 1; i < steps; i++)
push_back(LaserBoy_real_vertex( LaserBoy_3D_double(_from + (delta * i)),
(LaserBoy_color)to,
to.k,
to.c
)
);
//----------------------------------------------------------------
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(const LaserBoy_3D_double& p,
const LaserBoy_color c
) // 3D cross function
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
push_back(LaserBoy_real_vertex( p.x, p.y, p.z, c.r, c.g, c.b, LASERBOY_BLANKING_BIT, 0));
push_back(LaserBoy_real_vertex( p.x, p.y, p.z, c.r, c.g, c.b, 0, 0));
push_back(LaserBoy_real_vertex(-32767.0, p.y, p.z, c.r, c.g, c.b, LASERBOY_BLANKING_BIT, 0));
push_back(LaserBoy_real_vertex( 32767.0, p.y, p.z, c.r, c.g, c.b, 0, 0));
push_back(LaserBoy_real_vertex( p.x, -32767.0, p.z, c.r, c.g, c.b, LASERBOY_BLANKING_BIT, 0));
push_back(LaserBoy_real_vertex( p.x, 32767.0, p.z, c.r, c.g, c.b, 0, 0));
push_back(LaserBoy_real_vertex( p.x, p.y, -32767.0, c.r, c.g, c.b, LASERBOY_BLANKING_BIT, 0));
push_back(LaserBoy_real_vertex( p.x, p.y, 32767.0, c.r, c.g, c.b, 0, 0));
sync_rgb_and_palette();
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_frame_set& font_frames,
const u32string& character_list,
const string& text,
const double char_width,
const double mono_font_space,
const double super_diacritic_gap,
const bool bond_word,
const bool bond_line
)
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{ // fixed spaced font constructor
if(text.size() == 0)
real_segment_error = LASERBOY_EMPTY_STRING_ERROR;
else
{
wstring_convert, char32_t> conv_utf8_utf32;
//--------------------------------------------------------------------
bool first_glyph_rendered = false;
size_t text_index = 0,
character_count = 0,
vertex_index;
LaserBoy_3D_double float_3D;
LaserBoy_real_vertex vertex;
LaserBoy_real_segment character(55, false),
diacritc (55, false);
string _text = text;
u32string u32_text;
//--------------------------------------------------------------------
for(text_index = 0; text_index < _text.size(); text_index++)
{
if(_text[text_index] == 0x0d)
_text.erase(text_index);
}
text_index = 0;
u32_text = conv_utf8_utf32.from_bytes(_text);
//--------------------------------------------------------------------
if(character_list.find(u32_text[text_index]) == string::npos) // character not found
character = LaserBoy_real_segment(u32_text[text_index]);
else
character = font_frames[character_list.find(u32_text[text_index])].to_real_segment();
//--------------------------------------------------------------------
character.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
while( (text_index + 1) < u32_text.size()
&& is_super_diacritic(u32_text[text_index + 1])
)
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
{
diacritc = LaserBoy_real_segment(u32_text[text_index + 1]);
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
}
else
{
diacritc = font_frames[character_list.find(u32_text[text_index + 1])].to_real_segment();
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
diacritc.move(LaserBoy_3D_double(0.0,
-diacritc.min_y()
+ character.max_y()
+ (super_diacritic_gap * LASERBOY_MAX_SHORT),
0.0
)
);
}
character += diacritc;
character.convert_blank_to_black();
text_index++;
}
//--------------------------------------------------------------------
while( (text_index + 1) < u32_text.size()
&& is_sub_diacritic(u32_text[text_index + 1])
)
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
diacritc = LaserBoy_real_segment(u32_text[text_index + 1]);
else
diacritc = font_frames[character_list.find(u32_text[text_index + 1])].to_real_segment();
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
character += diacritc;
character.convert_blank_to_black();
text_index++;
}
//--------------------------------------------------------------------
float_3D = (LaserBoy_3D_double)character.at(0);
vertex.blank();
vertex.c = 0;
vertex.r = 255;
vertex.g = 0;
vertex.b = 0;
vertex = float_3D;
push_back(vertex);
vertex.unblank();
//--------------------------------------------------------------------
// UTF-8 Diacritic Range: Decimal 768-879. Hex 0300-036F
//--------------------------------------------------------------------
for(text_index = 0; text_index < u32_text.size(); text_index++)
{
if(u32_text[text_index] != 0x00000020) // [space]
{
if(character_list.find(u32_text[text_index]) == string::npos) // character not found
character = LaserBoy_real_segment(u32_text[text_index]);
else
character = font_frames[character_list.find(u32_text[text_index])].to_real_segment();
character.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
//------------------------------------------------------------
while( (text_index + 1) < u32_text.size()
&& is_super_diacritic(u32_text[text_index + 1])
)
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
{
diacritc = LaserBoy_real_segment(u32_text[text_index + 1]);
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
}
else
{
diacritc = font_frames[character_list.find(u32_text[text_index + 1])].to_real_segment();
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
diacritc.move(LaserBoy_3D_double(0.0,
-diacritc.min_y()
+ character.max_y()
+ (super_diacritic_gap * LASERBOY_MAX_SHORT),
0.0
)
);
}
character += diacritc;
character.convert_blank_to_black();
text_index++;
}
//------------------------------------------------------------
while( (text_index + 1) < u32_text.size()
&& is_sub_diacritic(u32_text[text_index + 1])
)
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
diacritc = LaserBoy_real_segment(u32_text[text_index + 1]);
else
diacritc = font_frames[character_list.find(u32_text[text_index + 1])].to_real_segment();
character += diacritc;
character.convert_blank_to_black();
text_index++;
}
//------------------------------------------------------------
for(vertex_index = 0; vertex_index < character.size(); vertex_index++)
{
float_3D = character.at(vertex_index);
//--------------------------------------------------------
float_3D.x = float_3D.x + ( character_count
* ( mono_font_space
* LASERBOY_MAX_SHORT
)
);
//--------------------------------------------------------
if(vertex_index && character.at(vertex_index).is_black(p_space->black_level))
push_back(LaserBoy_real_vertex(float_3D,
LaserBoy_color(0, 0, 0),
vertex.k,
255
)
);
else
push_back(LaserBoy_real_vertex(float_3D,
LaserBoy_color(255, 255, 255),
vertex.k,
55
)
);
if(character.at(vertex_index).is_blank())
{
if(character_count && (bond_word || bond_line)) // not the first glyph
{
back().r = 0;
back().g = 0;
back().b = 0;
back().c = 255;
}
else
back().blank();
}
}
first_glyph_rendered = true;
character_count++;
} // end if(u32_text[text_index] != 0x00000020) // [space]
else
{
character_count++;
while( (text_index + 1) < u32_text.size()
&& u32_text[text_index + 1] == 0x00000020 // [space]
)
{
text_index++;
character_count++;
}
//------------------------------------------------------------
if((text_index + 1) < (u32_text.size() - 1))
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
float_3D = LaserBoy_3D_double(0.0, 0.0, 0.0);
else
float_3D = font_frames[character_list.find(u32_text[text_index + 1])].at(0);
//--------------------------------------------------------
float_3D.x = float_3D.x + ( ( character_count
+ 1
)
* ( mono_font_space
* LASERBOY_MAX_SHORT
)
);
//--------------------------------------------------------
if(first_glyph_rendered && bond_line)
push_back(LaserBoy_real_vertex(float_3D,
LaserBoy_color(0, 0, 0),
vertex.k,
255
)
);
else
{
push_back(LaserBoy_real_vertex(float_3D,
LaserBoy_color(255, 255, 255),
vertex.k,
55
)
);
back().blank();
}
}
}
} // end for(text_index = 0; text_index < (int)u32_text.size(); text_index++)
reduce_blank_vectors();
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_frame_set& font_frames,
const u32string& character_list,
const string& text,
const double char_width,
const double vari_font_gap,
const double vari_font_space,
const double super_diacritic_gap,
const bool bond_word,
const bool bond_line
)
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{ // variable spaced font constructor
if(text.size() == 0)
real_segment_error = LASERBOY_EMPTY_STRING_ERROR;
else
{
wstring_convert, char32_t> conv_utf8_utf32;
//--------------------------------------------------------------------
bool first_glyph_rendered = false;
size_t text_index = 0,
vertex_index;
double glyph_offset,
width_of_a_space = 0.0,
accumulated_offset = 0.0;
LaserBoy_3D_double float_3D;
LaserBoy_real_vertex vertex;
LaserBoy_real_segment character(55, false),
diacritc (55, false);
string _text = text;
u32string u32_text;
//--------------------------------------------------------------------
for(text_index = 0; text_index < _text.size(); text_index++)
{
if(_text[text_index] == 0x0d)
_text.erase(text_index);
}
text_index = 0;
u32_text = conv_utf8_utf32.from_bytes(_text);
//--------------------------------------------------------------------
if(character_list.find(u32_text[text_index]) == string::npos) // character not found
character = LaserBoy_real_segment(u32_text[text_index]);
else
character = font_frames[character_list.find(u32_text[text_index])].to_real_segment();
character.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
//--------------------------------------------------------------------
while( (text_index + 1) < u32_text.size()
&& is_super_diacritic(u32_text[text_index + 1])
)
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
{
diacritc = LaserBoy_real_segment(u32_text[text_index + 1]);
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
}
else
{
diacritc = font_frames[character_list.find(u32_text[text_index + 1])].to_real_segment();
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
diacritc.move(LaserBoy_3D_double( 0.0,
-diacritc.min_y()
+ character.max_y()
+ (super_diacritic_gap * LASERBOY_MAX_SHORT),
0.0
)
);
}
character += diacritc;
character.convert_blank_to_black();
text_index++;
}
//--------------------------------------------------------------------
while( (text_index + 1) < u32_text.size()
&& is_sub_diacritic(u32_text[text_index + 1])
)
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
diacritc = LaserBoy_real_segment(u32_text[text_index + 1]);
else
diacritc = font_frames[character_list.find(u32_text[text_index + 1])].to_real_segment();
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
character += diacritc;
character.convert_blank_to_black();
text_index++;
}
//--------------------------------------------------------------------
float_3D = (LaserBoy_3D_double)character.at(0);
vertex.blank();
vertex.c = 0;
vertex.r = 255;
vertex.g = 0;
vertex.b = 0;
vertex = float_3D;
push_back(vertex);
vertex.unblank();
//--------------------------------------------------------------------
if(vari_font_space < 0.0)
{
for(size_t i = 0; i < font_frames.size(); i++)
if(width_of_a_space < font_frames[i].width())
width_of_a_space = font_frames[i].width();
}
else
width_of_a_space = (LASERBOY_MAX_SHORT * vari_font_space);
//--------------------------------------------------------------------
// UTF-8 Diacritic Range: Decimal 768-879. Hex 0300-036F
//--------------------------------------------------------------------
for(text_index = 0; text_index < u32_text.size(); text_index++)
{
if( u32_text[text_index] != 0x00000020) // [space]
{
if(character_list.find(u32_text[text_index]) == string::npos) // character not found
character = LaserBoy_real_segment(u32_text[text_index]);
else
character = font_frames[character_list.find(u32_text[text_index])].to_real_segment();
character.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
//------------------------------------------------------------
while( (text_index + 1) < u32_text.size()
&& is_super_diacritic(u32_text[text_index + 1])
)
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
{
diacritc = LaserBoy_real_segment(u32_text[text_index + 1]);
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
}
else
{
diacritc = font_frames[character_list.find(u32_text[text_index + 1])].to_real_segment();
diacritc.scale(LaserBoy_3D_double(char_width, 1.0, 1.0));
diacritc.move(LaserBoy_3D_double( 0.0,
-diacritc.min_y()
+ character.max_y()
+ (super_diacritic_gap * LASERBOY_MAX_SHORT),
0.0
)
);
}
character += diacritc;
character.convert_blank_to_black();
text_index++;
}
//------------------------------------------------------------
while( (text_index + 1) < u32_text.size()
&& is_sub_diacritic(u32_text[text_index + 1])
)
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
diacritc = LaserBoy_real_segment(u32_text[text_index + 1]);
else
diacritc = font_frames[character_list.find(u32_text[text_index + 1])].to_real_segment();
character += diacritc;
character.convert_blank_to_black();
text_index++;
}
//------------------------------------------------------------
glyph_offset = character.segment_left().x;
for(vertex_index = 0; vertex_index < character.size(); vertex_index++)
{
float_3D = character.at(vertex_index);
float_3D.x = (float_3D.x - glyph_offset) + accumulated_offset;
if(character.at(vertex_index).is_black(p_space->black_level))
push_back(LaserBoy_real_vertex(float_3D,
LaserBoy_color(0, 0, 0),
vertex.k,
255
)
);
else
push_back(LaserBoy_real_vertex(float_3D,
LaserBoy_color(255, 255, 255),
vertex.k,
55
)
);
if(character.at(vertex_index).is_blank())
{
if(text_index && (bond_word || bond_line)) // not the first glyph
{
back().r = 0;
back().g = 0;
back().b = 0;
back().c = 255;
}
else
back().blank();
}
} // end for(vertex_index = 0; vertex_index < (int)font_frames[font_frame_index].size(); vertex_index++)
accumulated_offset += ( character.width()
+ ( vari_font_gap
* LASERBOY_MAX_SHORT // percent of square space
)
);
first_glyph_rendered = true;
} // end if(u32_text[text_index] != 0x00000020) // [space]
else // it's a space
{
accumulated_offset += ( width_of_a_space
+ ( vari_font_gap
* LASERBOY_MAX_SHORT // percent of square space
)
);
while( (text_index + 1) < u32_text.size()
&& u32_text[text_index + 1] == 0x00000020 // [space]
)
{
accumulated_offset += ( width_of_a_space
+ ( vari_font_gap
* LASERBOY_MAX_SHORT // percent of square space
)
);
text_index++;
}
if((text_index + 1) < (u32_text.size() - 1))
{
if(character_list.find(u32_text[text_index + 1]) == string::npos) // character not found
{
glyph_offset = 0.0;
float_3D = LaserBoy_3D_double(0.0, 0.0, 0.0);
}
else
{
glyph_offset = font_frames[character_list.find(u32_text[text_index + 1])].segment_left().x;
float_3D = font_frames[character_list.find(u32_text[text_index + 1])].at(0);
}
float_3D.x = (float_3D.x - glyph_offset) + accumulated_offset;
if(first_glyph_rendered && bond_line)
push_back(LaserBoy_real_vertex(float_3D,
LaserBoy_color(0, 0, 0),
vertex.k,
255
)
);
else
{
push_back(LaserBoy_real_vertex(float_3D,
LaserBoy_color(255, 255, 255),
vertex.k,
55
)
);
back().blank();
}
}
}
} // end for(text_index = 0; text_index < (int)u32_text.size(); text_index++)
reduce_blank_vectors();
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(char32_t unichar) // uncicode not found frame
{
LaserBoy_real_segment rs;
if(p_space->font_frames.size())
{
string text = as_hex_string(unichar);
rs.palette_index = LASERBOY_ILDA_DEFAULT;
if(text.substr(0, 4) == "0000")
text = text.substr(4, 4);
rs = LaserBoy_real_segment(p_space->font_frames,
p_space->font_index,
text,
1.0,
1.0,
0.05, // NA
true,
true
);
rs.convert_black_to_blank();
rs.reduce_blank_vectors();
rs.convert_blank_to_black();
rs.scale(LaserBoy_3D_double(1.0 / text.size(), 1.0 / text.size(), 0.0));
rs.scale(LaserBoy_3D_double(0.85, 0.85, 0.0));
rs.center_y();
rs.move(LaserBoy_3D_double(2600 - rs.min_x(), LASERBOY_HALF_SHORT, 0.0));
}
else
{
rs.push_back(LaserBoy_real_vertex( 0, 0, 0, 255, 255, 255, LASERBOY_BLANKING_BIT, 55));
rs.push_back(LaserBoy_real_vertex(LASERBOY_MAX_SHORT, LASERBOY_MAX_SHORT, 0, 255, 255, 255, 0, 55));
rs.push_back(LaserBoy_real_vertex(LASERBOY_MAX_SHORT, 0, 0, 255, 255, 255, LASERBOY_BLANKING_BIT, 55));
rs.push_back(LaserBoy_real_vertex( 0, LASERBOY_MAX_SHORT, 0, 255, 255, 255, 0, 55));
}
rs.push_back(LaserBoy_real_vertex( 0, 0, 0, 255, 255, 255, LASERBOY_BLANKING_BIT, 55));
rs.push_back(LaserBoy_real_vertex(LASERBOY_MAX_SHORT, 0, 0, 255, 255, 255, 0, 55));
rs.push_back(LaserBoy_real_vertex(LASERBOY_MAX_SHORT, LASERBOY_MAX_SHORT, 0, 255, 255, 255, 0, 55));
rs.push_back(LaserBoy_real_vertex( 0, LASERBOY_MAX_SHORT, 0, 255, 255, 255, 0, 55));
rs.push_back(LaserBoy_real_vertex( 0, 0, 0, 255, 255, 255, 0, 55));
*this += rs;
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(const double fixed_radius,
const double rhodonea_numerator,
const double rhodonea_denominator,
const double start,
const double duration,
double iterations
) // ::rhodonea
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double ratio = 1.0,
blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating rhodonea");
if(rhodonea_denominator != 0.0)
ratio = rhodonea_numerator / rhodonea_denominator;
vertex.x = fixed_radius * cos(ratio * start) * cos(start);
vertex.y = fixed_radius * cos(ratio * start) * sin(start);
vertex.z = 0.0;
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = fixed_radius * cos(ratio * time) * cos(time);
vertex.y = fixed_radius * cos(ratio * time) * sin(time);
push_back(vertex);
}
vertex.x = fixed_radius * cos(ratio * end) * cos(end);
vertex.y = fixed_radius * cos(ratio * end) * sin(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
const double fixed_radius,
const double rhodonea_numerator,
const double rhodonea_denominator,
const double start,
const double duration,
double iterations
) // ::oscillator_rhodonea
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double ratio = 1.0,
blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating oscillator_rhodonea");
if(rhodonea_denominator != 0.0)
ratio = rhodonea_numerator / rhodonea_denominator;
LBO1.phase += (LBO1.phase_cycle / 4.0);
LBO2.phase += (LBO2.phase_cycle / 4.0);
LBO3.phase += (LBO3.phase_cycle / 4.0);
LBO1_.phase += (LBO1_.phase_cycle / 4.0);
LBO2_.phase += (LBO2_.phase_cycle / 4.0);
LBO3_.phase += (LBO3_.phase_cycle / 4.0);
vertex.x = fixed_radius
* LBO1(ratio * start)
* LBO2(start);
vertex.y = fixed_radius
* LBO3(ratio * start)
* LBO4(start);
vertex.z = 0.0;
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = fixed_radius
* LBO1.blend(LBO1_, blend)(ratio * time)
* LBO2.blend(LBO2_, blend)(time);
vertex.y = fixed_radius
* LBO3.blend(LBO3_, blend)(ratio * time)
* LBO4.blend(LBO4_, blend)(time);
push_back(vertex);
}
vertex.x = fixed_radius
* LBO1_(ratio * end)
* LBO2_(end);
vertex.y = fixed_radius
* LBO3_(ratio * end)
* LBO4_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(const double fixed_radius,
const double roller_radius,
const double roller_offset,
const double start,
const double duration,
double iterations,
const char dud
) // ::epicycloid
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double ratio = 1.0,
blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating epitrochoid / epicycloid");
if(roller_radius != 0.0)
ratio = fixed_radius / roller_radius;
vertex.x = roller_radius * (ratio + 1) * cos(start)
- roller_offset * cos((ratio + 1) * start);
vertex.y = roller_radius * (ratio + 1) * sin(start)
- roller_offset * sin((ratio + 1) * start);
vertex.z = 0.0;
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = roller_radius * (ratio + 1) * cos(time)
- roller_offset * cos((ratio + 1) * time);
vertex.y = roller_radius * (ratio + 1) * sin(time)
- roller_offset * sin((ratio + 1) * time);
push_back(vertex);
}
vertex.x = roller_radius * (ratio + 1) * cos(end)
- roller_offset * cos((ratio + 1) * end);
vertex.y = roller_radius * (ratio + 1) * sin(end)
- roller_offset * sin((ratio + 1) * end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
const double fixed_radius,
const double roller_radius,
const double roller_offset,
const double start,
const double duration,
double iterations,
const char dud
) // ::oscillator_epicycloid
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double ratio = 1.0,
blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating oscillator_epitrochoid / oscillator_epicycloid");
LBO1.phase += (LBO1.phase_cycle / 4.0);
LBO2.phase += (LBO2.phase_cycle / 4.0);
LBO1_.phase += (LBO1_.phase_cycle / 4.0);
LBO2_.phase += (LBO2_.phase_cycle / 4.0);
if(roller_radius != 0.0)
ratio = fixed_radius / roller_radius;
vertex.x = roller_radius * (ratio + 1) * LBO1(start)
- roller_offset * LBO2((ratio + 1) * start);
vertex.y = roller_radius * (ratio + 1) * LBO3(start)
- roller_offset * LBO4((ratio + 1) * start);
vertex.z = 0.0;
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = roller_radius * (ratio + 1) * LBO1.blend(LBO1_, blend)(time)
- roller_offset * LBO2.blend(LBO2_, blend)((ratio + 1) * time);
vertex.y = roller_radius * (ratio + 1) * LBO3.blend(LBO3_, blend)(time)
- roller_offset * LBO4.blend(LBO4_, blend)((ratio + 1) * time);
push_back(vertex);
}
vertex.x = roller_radius * (ratio + 1) * LBO1_(end)
- roller_offset * LBO2_((ratio + 1) * end);
vertex.y = roller_radius * (ratio + 1) * LBO3_(end)
- roller_offset * LBO4_((ratio + 1) * end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(const double fixed_radius,
const double roller_radius,
const double roller_offset,
const double start,
const double duration,
double iterations,
const short dud
) // ::hypocycloid
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double ratio = 1.0,
blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating hypotrochoid / hypocycloid");
if(roller_radius != 0.0)
ratio = fixed_radius / roller_radius;
vertex.x = (fixed_radius - roller_radius) * cos(start)
+ roller_offset * cos((ratio - 1) * start);
vertex.y = (fixed_radius - roller_radius) * sin(start)
- roller_offset * sin((ratio - 1) * start);
vertex.z = 0.0;
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = (fixed_radius - roller_radius) * cos(time)
+ roller_offset * cos((ratio - 1) * time);
vertex.y = (fixed_radius - roller_radius) * sin(time)
- roller_offset * sin((ratio - 1) * time);
push_back(vertex);
}
vertex.x = (fixed_radius - roller_radius) * cos(end)
+ roller_offset * cos((ratio - 1) * end);
vertex.y = (fixed_radius - roller_radius) * sin(end)
- roller_offset * sin((ratio - 1) * end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
const double fixed_radius,
const double roller_radius,
const double roller_offset,
const double start,
const double duration,
double iterations,
const short dud
) // ::oscillator_hypocycloid
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double ratio = 1.0,
blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating oscillator_hypotrochoid / oscillator_hypocycloid");
LBO1.phase += (LBO1.phase_cycle / 4.0);
LBO2.phase += (LBO2.phase_cycle / 4.0);
LBO1_.phase += (LBO1_.phase_cycle / 4.0);
LBO2_.phase += (LBO2_.phase_cycle / 4.0);
if(roller_radius != 0.0)
ratio = fixed_radius / roller_radius;
vertex.x = (fixed_radius - roller_radius) * LBO1(start)
+ roller_offset * LBO2((ratio - 1) * start);
vertex.y = (fixed_radius - roller_radius) * LBO3(start)
- roller_offset * LBO4((ratio - 1) * start);
vertex.z = 0.0;
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = (fixed_radius - roller_radius) * LBO1.blend(LBO1_, blend)(time)
+ roller_offset * LBO2.blend(LBO2_, blend)((ratio - 1) * time);
vertex.y = (fixed_radius - roller_radius) * LBO3.blend(LBO3_, blend)(time)
- roller_offset * LBO4.blend(LBO4_, blend)((ratio - 1) * time);
push_back(vertex);
}
vertex.x = (fixed_radius - roller_radius) * LBO1_(end)
+ roller_offset * LBO2_((ratio - 1) * end);
vertex.y = (fixed_radius - roller_radius) * LBO3_(end)
- roller_offset * LBO4_((ratio - 1) * end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO1_,
const double start,
const double duration,
double iterations
) // ::oscillator
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating oscillator");
vertex.x = start;
vertex.y = LBO1(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = time;
vertex.y = LBO1.blend(LBO1_, blend)(time);
push_back(vertex);
}
vertex.x = end;
vertex.y = LBO1_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations
) // ::oscillator_sum
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating oscillator_sum");
vertex.x = start;
vertex.y = LBO1(start) + LBO2(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = time;
vertex.y = LBO1.blend(LBO1_, blend)(time) + LBO2.blend(LBO2_, blend)(time);
push_back(vertex);
}
vertex.x = end;
vertex.y = LBO1_(end) + LBO2_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations,
const char dud
) // ::oscillator_xy
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating oscillator_xy");
vertex.x = LBO1(start);
vertex.y = LBO2(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = LBO1.blend(LBO1_, blend)(time);
vertex.y = LBO2.blend(LBO2_, blend)(time);
push_back(vertex);
}
vertex.x = LBO1_(end);
vertex.y = LBO2_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
const double start,
const double duration,
double iterations
) // ::oscillator_xyz
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating oscillator_xyz");
vertex.x = LBO1(start);
vertex.y = LBO2(start);
vertex.z = LBO3(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = LBO1.blend(LBO1_, blend)(time);
vertex.y = LBO2.blend(LBO2_, blend)(time);
vertex.z = LBO3.blend(LBO3_, blend)(time);
push_back(vertex);
}
vertex.x = LBO1_(end);
vertex.y = LBO2_(end);
vertex.z = LBO3_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
const double start,
const double duration,
double iterations
) // ::harmonograph
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating harmonograph");
vertex.x = LBO1(start) + LBO2(start);
vertex.y = LBO3(start) + LBO4(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = LBO1.blend(LBO1_, blend)(time)
+ LBO2.blend(LBO2_, blend)(time);
vertex.y = LBO3.blend(LBO3_, blend)(time)
+ LBO4.blend(LBO4_, blend)(time);
push_back(vertex);
}
vertex.x = LBO1_(end)
+ LBO2_(end);
vertex.y = LBO3_(end)
+ LBO4_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO5,
LaserBoy_oscillator LBO6,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
LaserBoy_oscillator LBO5_,
LaserBoy_oscillator LBO6_,
const double start,
const double duration,
double iterations
) // ::harmonograph_xyz
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating harmonograph_xyz");
vertex.x = LBO1(start) + LBO2(start);
vertex.y = LBO3(start) + LBO4(start);
vertex.z = LBO5(start) + LBO6(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = LBO1.blend(LBO1_, blend)(time)
+ LBO2.blend(LBO2_, blend)(time);
vertex.y = LBO3.blend(LBO3_, blend)(time)
+ LBO4.blend(LBO4_, blend)(time);
vertex.z = LBO5.blend(LBO5_, blend)(time)
+ LBO6.blend(LBO6_, blend)(time);
push_back(vertex);
}
vertex.x = LBO1_(end)
+ LBO2_(end);
vertex.y = LBO3_(end)
+ LBO4_(end);
vertex.z = LBO5_(end)
+ LBO6_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations,
const short dud
) // ::amplitude_mod
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating amplitude_mod");
vertex.x = start;
vertex.y = LBO1(start) * LBO2(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = time;
vertex.y = LBO1.blend(LBO1_, blend)(time)
* LBO2.blend(LBO2_, blend)(time);
push_back(vertex);
}
vertex.x = end;
vertex.y = LBO1_(end)
* LBO2_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
const double start,
const double duration,
double iterations,
const char dud
) // ::amplitude_mod_xy
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating amplitude_mod_xy");
vertex.x = LBO1(start) * LBO2(start);
vertex.y = LBO3(start) * LBO4(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = LBO1.blend(LBO1_, blend)(time)
* LBO2.blend(LBO2_, blend)(time);
vertex.y = LBO3.blend(LBO3_, blend)(time)
* LBO4.blend(LBO4_, blend)(time);
push_back(vertex);
}
vertex.x = LBO1_(end)
* LBO2_(end);
vertex.y = LBO3_(end)
* LBO4_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO5,
LaserBoy_oscillator LBO6,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
LaserBoy_oscillator LBO5_,
LaserBoy_oscillator LBO6_,
const double start,
const double duration,
double iterations,
const char dud
) // ::amplitude_mod_xyz
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating amplitude_mod_xyz");
vertex.x = LBO1(start) * LBO2(start);
vertex.y = LBO3(start) * LBO4(start);
vertex.z = LBO5(start) * LBO6(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = LBO1.blend(LBO1_, blend)(time)
* LBO2.blend(LBO2_, blend)(time);
vertex.y = LBO3.blend(LBO3_, blend)(time)
* LBO4.blend(LBO4_, blend)(time);
vertex.z = LBO5.blend(LBO5_, blend)(time)
* LBO6.blend(LBO6_, blend)(time);
push_back(vertex);
}
vertex.x = LBO1_(end)
* LBO2_(end);
vertex.y = LBO3_(end)
* LBO4_(end);
vertex.z = LBO5_(end)
* LBO6_(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations,
const int dud
) // ::frequency_mod
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
LaserBoy_oscillator LBO;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating frequency_mod");
vertex.x = start;
LBO = LBO1;
LBO.frequency = LBO1.frequency * LBO2(start);
vertex.y = LBO(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = time;
LBO = LBO1.blend(LBO1_, blend);
LBO.frequency = LBO1.blend(LBO1_, blend).frequency
* LBO2.blend(LBO2_, blend)(time);
vertex.y = LBO(time);
push_back(vertex);
}
LBO = LBO1_;
LBO.frequency = LBO1_.frequency
* LBO2_(end);
vertex.y = LBO(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
const double start,
const double duration,
double iterations,
const short dud
) // ::frequency_mod_xy
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
LaserBoy_oscillator LBO;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating frequency_mod_xy");
LBO = LBO1;
LBO.frequency = LBO1.frequency * LBO2(start);
vertex.x = LBO(start);
LBO = LBO3;
LBO.frequency = LBO3.frequency * LBO4(start);
vertex.y = LBO(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
LBO = LBO1.blend(LBO1_, blend);
LBO.frequency = LBO1.blend(LBO1_, blend).frequency
* LBO2.blend(LBO2_, blend)(time);
vertex.x = LBO(time);
LBO = LBO3.blend(LBO3_, blend);
LBO.frequency = LBO3.blend(LBO3_, blend).frequency
* LBO4.blend(LBO4_, blend)(time);
vertex.y = LBO(time);
push_back(vertex);
}
LBO = LBO1_;
LBO.frequency = LBO1_.frequency
* LBO2_(end);
vertex.x = LBO(end);
LBO = LBO3_;
LBO.frequency = LBO3_.frequency
* LBO4_(end);
vertex.y = LBO(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO5,
LaserBoy_oscillator LBO6,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
LaserBoy_oscillator LBO5_,
LaserBoy_oscillator LBO6_,
const double start,
const double duration,
double iterations,
const short dud
) // ::frequency_mod_xyz
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
LaserBoy_oscillator LBO;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating frequency_mod_xyz");
LBO = LBO1;
LBO.frequency = LBO1.frequency * LBO2(start);
vertex.x = LBO(start);
LBO = LBO3;
LBO.frequency = LBO3.frequency * LBO4(start);
vertex.y = LBO(start);
LBO = LBO3;
LBO.frequency = LBO5.frequency * LBO6(start);
vertex.z = LBO(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
LBO = LBO1.blend(LBO1_, blend);
LBO.frequency = LBO1.blend(LBO1_, blend).frequency
* LBO2.blend(LBO2_, blend)(time);
vertex.x = LBO(time);
LBO = LBO3.blend(LBO3_, blend);
LBO.frequency = LBO3.blend(LBO3_, blend).frequency
* LBO4.blend(LBO4_, blend)(time);
vertex.y = LBO(time);
LBO = LBO5.blend(LBO5_, blend);
LBO.frequency = LBO5.blend(LBO5_, blend).frequency
* LBO6.blend(LBO6_, blend)(time);
vertex.z = LBO(time);
push_back(vertex);
}
LBO = LBO1_;
LBO.frequency = LBO1_.frequency
* LBO2_(end);
vertex.x = LBO(end);
LBO = LBO3_;
LBO.frequency = LBO3_.frequency
* LBO4_(end);
vertex.y = LBO(end);
LBO = LBO5_;
LBO.frequency = LBO5_.frequency
* LBO6_(end);
vertex.z = LBO(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations,
const float dud
) // ::phase_mod
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
LaserBoy_oscillator LBO;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating phase_mod");
vertex.x = start;
LBO = LBO1;
LBO.phase = LBO1.phase + LBO2(start) * (LBO1.phase_cycle / 2.0);
vertex.y = LBO(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = time;
LBO = LBO1;
LBO.phase = LBO1.blend(LBO1_, blend).phase
+ LBO2.blend(LBO2_, blend)(time)
* (LBO1.phase_cycle / 2.0);
vertex.y = LBO(time);
push_back(vertex);
}
vertex.x = end;
LBO = LBO1_;
LBO.phase = LBO1_.phase + LBO2_(end) * (LBO1_.phase_cycle / 2.0);
vertex.y = LBO(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
const double start,
const double duration,
double iterations,
const int dud
) // ::phase_mod_xy
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
LaserBoy_oscillator LBO;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating phase_mod_xy");
LBO = LBO1;
LBO.phase = LBO1.phase + LBO2(start) * (LBO1.phase_cycle / 2.0);
vertex.x = LBO(start);
LBO = LBO3;
LBO.phase = LBO3.phase + LBO4(start) * (LBO3.phase_cycle / 2.0);
vertex.y = LBO(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
LBO = LBO1.blend(LBO1_, blend);
LBO.phase = LBO1.blend(LBO1_, blend).phase
+ LBO2.blend(LBO2_, blend)(time) * (LBO1.phase_cycle / 2.0);
vertex.x = LBO(time);
LBO = LBO3.blend(LBO3_, blend);
LBO.phase = LBO3.blend(LBO3_, blend).phase
+ LBO4.blend(LBO4_, blend)(time) * (LBO3.phase_cycle / 2.0);
vertex.y = LBO(time);
push_back(vertex);
}
LBO = LBO1_;
LBO.phase = LBO1_.phase + LBO2_(end) * (LBO1_.phase_cycle / 2.0);
vertex.x = LBO(end);
LBO = LBO3;
LBO.phase = LBO3_.phase + LBO4_(end) * (LBO3_.phase_cycle / 2.0);
vertex.y = LBO(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO3,
LaserBoy_oscillator LBO4,
LaserBoy_oscillator LBO5,
LaserBoy_oscillator LBO6,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
LaserBoy_oscillator LBO3_,
LaserBoy_oscillator LBO4_,
LaserBoy_oscillator LBO5_,
LaserBoy_oscillator LBO6_,
const double start,
const double duration,
double iterations,
const int dud
) // ::phase_mod_xyz
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
LaserBoy_oscillator LBO;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating phase_mod_xyz");
LBO = LBO1;
LBO.phase = LBO1.phase + LBO2(start) * (LBO1.phase_cycle / 2.0);
vertex.x = LBO(start);
LBO = LBO3;
LBO.phase = LBO3.phase + LBO4(start) * (LBO3.phase_cycle / 2.0);
vertex.y = LBO(start);
LBO = LBO3;
LBO.phase = LBO5.phase + LBO6(start) * (LBO5.phase_cycle / 2.0);
vertex.z = LBO(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
LBO = LBO1.blend(LBO1_, blend);
LBO.phase = LBO1.blend(LBO1_, blend).phase
+ LBO2.blend(LBO2_, blend)(time) * (LBO1.phase_cycle / 2.0);
vertex.x = LBO(time);
LBO = LBO3.blend(LBO3_, blend);
LBO.phase = LBO3.blend(LBO3_, blend).phase
+ LBO4.blend(LBO4_, blend)(time) * (LBO3.phase_cycle / 2.0);
vertex.y = LBO(time);
LBO = LBO5.blend(LBO5_, blend);
LBO.phase = LBO5.blend(LBO5_, blend).phase
+ LBO6.blend(LBO6_, blend)(time) * (LBO5.phase_cycle / 2.0);
vertex.z = LBO(time);
push_back(vertex);
}
LBO = LBO1_;
LBO.phase = LBO1_.phase + LBO2_(end) * (LBO1_.phase_cycle / 2.0);
vertex.x = LBO(end);
LBO = LBO3_;
LBO.phase = LBO3_.phase + LBO4(end) * (LBO3_.phase_cycle / 2.0);
vertex.y = LBO(end);
LBO = LBO5_;
LBO.phase = LBO5_.phase + LBO6_(end) * (LBO5_.phase_cycle / 2.0);
vertex.z = LBO(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO1_,
const double start,
const double duration,
double iterations,
const char dud
) // ::polar
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating polar");
vertex.x = LBO1(start) * cos(start);
vertex.y = LBO1(start) * sin(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = LBO1.blend(LBO1_, blend)(time) * cos(time);
vertex.y = LBO1.blend(LBO1_, blend)(time) * sin(time);
push_back(vertex);
}
vertex.x = LBO1_(end) * cos(end);
vertex.y = LBO1_(end) * sin(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations,
const char dud1,
const char dud2
) // ::polar_sum
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating polar_sum");
vertex.x = (LBO1(start) + LBO2(start)) * cos(start);
vertex.y = (LBO1(start) + LBO2(start)) * sin(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = ( LBO1.blend(LBO1_, blend)(time)
+ LBO2.blend(LBO2_, blend)(time)) * cos(time);
vertex.y = ( LBO1.blend(LBO1_, blend)(time)
+ LBO2.blend(LBO2_, blend)(time)) * sin(time);
push_back(vertex);
}
vertex.x = ( LBO1_(end)
+ LBO2_(end)) * cos(end);
vertex.y = ( LBO1_(end)
+ LBO2_(end)) * sin(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations,
const short dud1,
const char dud2
) // ::polar_amplitude_mod
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating polar_amplitude_mod");
vertex.x = (LBO1(start) * LBO2(start)) * cos(start);
vertex.y = (LBO1(start) * LBO2(start)) * sin(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
vertex.x = ( LBO1.blend(LBO1_, blend)(time)
* LBO2.blend(LBO2_, blend)(time)) * cos(time);
vertex.y = ( LBO1.blend(LBO1_, blend)(time)
* LBO2.blend(LBO2_, blend)(time)) * sin(time);
push_back(vertex);
}
vertex.x = ( LBO1_(end)
* LBO2_(end)) * cos(end);
vertex.y = ( LBO1_(end)
* LBO2_(end)) * sin(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations,
const int dud1,
const char dud2
) // ::polar_frequency_mod
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
LaserBoy_oscillator LBO;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating polar_frequency_mod");
LBO = LBO1;
LBO.frequency = LBO1.frequency * LBO2(start);
vertex.x = LBO(start) * cos(start);
vertex.y = LBO(start) * sin(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
LBO = LBO1;
LBO.frequency = LBO1.blend(LBO1_, blend).frequency
* LBO2.blend(LBO2_, blend)(time);
vertex.x = LBO(time) * cos(time);
vertex.y = LBO(time) * sin(time);
push_back(vertex);
}
LBO = LBO1_;
LBO.frequency = LBO1_.frequency * LBO2_(end);
vertex.x = LBO(end) * cos(end);
vertex.y = LBO(end) * sin(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
LaserBoy_real_segment::LaserBoy_real_segment(LaserBoy_oscillator LBO1,
LaserBoy_oscillator LBO2,
LaserBoy_oscillator LBO1_,
LaserBoy_oscillator LBO2_,
const double start,
const double duration,
double iterations,
const float dud1,
const char dud2
) // ::polar_phase_mod
: vector(),
is_selected (false),
palette_index (LASERBOY_ILDA_DEFAULT),
real_segment_error (LASERBOY_OK)
{
bool iterations_is_int = close_to_int(iterations);
double blend,
increment,
time,
end = start + duration;
LaserBoy_real_vertex vertex;
LaserBoy_oscillator LBO;
reserve((size_t)iterations + 2);
p_space->p_GUI->display_state("calculating polar_phase_mod");
LBO = LBO1;
LBO.phase = LBO1.phase + LBO2(start) * (LBO1.phase_cycle / 2.0);
vertex.x = LBO(start) * cos(start);
vertex.y = LBO(start) * sin(start);
push_back(vertex);
vertex.unblank();
if(iterations >= 2 && duration > 0.0)
{
increment = duration / (iterations - 1.0);
for(time = start + increment; time <= end; time += increment)
{
blend = (time - start) / duration;
LBO = LBO1;
LBO.phase = LBO1.blend(LBO1_, blend).phase
+ LBO2.blend(LBO2_, blend)(time) * (LBO.phase_cycle / 2.0);
vertex.x = LBO(time) * cos(time);
vertex.y = LBO(time) * sin(time);
push_back(vertex);
}
LBO = LBO1_;
LBO.phase = LBO1_.phase
+ LBO2_(end) * (LBO.phase_cycle / 2.0);
vertex.x = LBO(end) * cos(end);
vertex.y = LBO(end) * sin(end);
if( iterations_is_int
&& ((back() | vertex) > LASERBOY_EPSILON)
)
push_back(vertex);
}
}
//############################################################################
size_t LaserBoy_real_segment::number_of_color_vectors() const
{
size_t count = 0;
if(size() > 1)
for(size_t i = 1; i < size(); i++)
if(at(i).is_color(p_space->black_level))
count++;
return count;
}
//############################################################################
size_t LaserBoy_real_segment::number_of_dark_vectors() const
{
size_t count = 0;
if(size() > 1)
for(size_t i = 1; i < size(); i++)
if(at(i).is_dark(p_space->black_level))
count++;
return count;
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::dimensions(LaserBoy_3D_double& real_offset, bool ignore_origin) const
{
size_t i,
start = 0;
LaserBoy_3D_double real_min = DBL_MAX,
real_max = -DBL_MAX;
if(ignore_origin)
start = 2;
for(i = start; i < size(); i++) // ignore the origin vector
{
if(at(i).x > real_max.x)
real_max.x = at(i).x;
if(at(i).x < real_min.x)
real_min.x = at(i).x;
if(at(i).y > real_max.y)
real_max.y = at(i).y;
if(at(i).y < real_min.y)
real_min.y = at(i).y;
if(at(i).z > real_max.z)
real_max.z = at(i).z;
if(at(i).z < real_min.z)
real_min.z = at(i).z;
}
real_offset.x = (real_max.x - ((real_max.x - real_min.x) / 2));
real_offset.y = (real_max.y - ((real_max.y - real_min.y) / 2));
real_offset.z = (real_max.z - ((real_max.z - real_min.z) / 2));
return LaserBoy_3D_double(real_max.x - real_min.x,
real_max.y - real_min.y,
real_max.z - real_min.z
);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::segment_front() const
{
if(size() > 1)
{
LaserBoy_3D_double front_;
front_.z = -DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(at(i).z > front_.z)
front_ = at(i);
return front_;
}
else
return LaserBoy_3D_double(0, 0, 0);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::segment_back() const
{
if(size() > 1)
{
LaserBoy_3D_double back_;
back_.z = DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(at(i).z < back_.z)
back_ = at(i);
return back_;
}
else
return LaserBoy_3D_double(0, 0, 0);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::segment_top() const
{
if(size() > 1)
{
LaserBoy_3D_double top_;
top_.y = -DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(at(i).y > top_.y)
top_ = at(i);
return top_;
}
else
return LaserBoy_3D_double(0, 0, 0);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::segment_bottom() const
{
if(size() > 1)
{
LaserBoy_3D_double bottom_;
bottom_.y = DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(at(i).y < bottom_.y)
bottom_ = at(i);
return bottom_;
}
else
return LaserBoy_3D_double(0, 0, 0);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::segment_right() const
{
if(size() > 1)
{
LaserBoy_3D_double right_;
right_.x = -DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(at(i).x > right_.x)
right_ = at(i);
return right_;
}
else
return LaserBoy_3D_double(0, 0, 0);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::segment_left() const
{
if(size() > 1)
{
LaserBoy_3D_double left_;
left_.x = DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(at(i).x < left_.x)
left_ = at(i);
return left_;
}
else
return LaserBoy_3D_double(0, 0, 0);
}
//############################################################################
double LaserBoy_real_segment::max_x() const
{
if(size() > 1)
{
double max = -DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(max <= at(i).x)
max = at(i).x;
return max;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::max_y() const
{
if(size() > 1)
{
double max = -DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(max <= at(i).y)
max = at(i).y;
return max;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::max_z() const
{
if(size() > 1)
{
double max = -DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(max <= at(i).z)
max = at(i).z;
return max;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::min_x() const
{
if(size() > 1)
{
double min = DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(min >= at(i).x)
min = at(i).x;
return min;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::min_y() const
{
if(size() > 1)
{
double min = DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(min >= at(i).y)
min = at(i).y;
return min;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::min_z() const
{
if(size() > 1)
{
double min = DBL_MAX;
for(size_t i = 0; i < size(); i++)
if(min >= at(i).z)
min = at(i).z;
return min;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::height() const
{
return max_y() - min_y();
}
//############################################################################
double LaserBoy_real_segment::width() const
{
return max_x() - min_x();
}
//############################################################################
double LaserBoy_real_segment::depth() const
{
return max_z() - min_z();
}
//############################################################################
double LaserBoy_real_segment::max_dimension() const
{
double max = 0;
if(width () > max) max = width ();
if(height() > max) max = height();
if(depth () > max) max = depth ();
return max;
}
//############################################################################
double LaserBoy_real_segment::max_distance_from_origin() const
{
if(size() > 1)
{
double max = 0.0,
d;
LaserBoy_3D_double origin;
for(size_t i = 0; i < size(); i++)
{
d = origin | at(i);
if(d > max)
max = d;
}
return max;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::max_distance_from_origin_xy() const
{
if(size() > 1)
{
double max = 0.0,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.z = 0;
d = origin | vertex;
if(d > max)
max = d;
}
return max;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::max_distance_from_origin_zy() const
{
if(size() > 1)
{
double max = 0.0,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.x = 0;
d = origin | vertex;
if(d > max)
max = d;
}
return max;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::max_distance_from_origin_xz() const
{
if(size() > 1)
{
double max = 0.0,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.y = 0;
d = origin | vertex;
if(d > max)
max = d;
}
return max;
}
else
return 0.0;
}
//############################################################################
size_t LaserBoy_real_segment::i_max_distance_from_origin_xy() const
{
size_t index = 0;
if(size() > 1)
{
double max = 0.0,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.z = 0;
d = origin | vertex;
if(d > max)
{
index = i;
max = d;
}
}
}
return index;
}
//############################################################################
size_t LaserBoy_real_segment::i_max_distance_from_origin_zy() const
{
size_t index = 0;
if(size() > 1)
{
double max = 0.0,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.x = 0;
d = origin | vertex;
if(d > max)
{
index = i;
max = d;
}
}
}
return index;
}
//############################################################################
size_t LaserBoy_real_segment::i_max_distance_from_origin_xz() const
{
size_t index = 0;
if(size() > 1)
{
double max = 0.0,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.y = 0;
d = origin | vertex;
if(d > max)
{
index = i;
max = d;
}
}
}
return index;
}
//############################################################################
double LaserBoy_real_segment::min_distance_from_origin() const
{
if(size() > 1)
{
double min = DBL_MAX,
d;
LaserBoy_3D_double origin;
for(size_t i = 0; i < size(); i++)
{
d = origin | at(i);
if(d == 0.0)
return 0.0;
if(d < min)
min = d;
}
return min;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::min_distance_from_origin_xy() const
{
if(size() > 1)
{
double min = DBL_MAX,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.z = 0;
d = origin | vertex;
if(d == 0.0)
return 0.0;
if(d < min)
min = d;
}
return min;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::min_distance_from_origin_zy() const
{
if(size() > 1)
{
double min = DBL_MAX,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.x = 0;
d = origin | vertex;
if(d == 0.0)
return 0.0;
if(d < min)
min = d;
}
return min;
}
else
return 0.0;
}
//############################################################################
double LaserBoy_real_segment::min_distance_from_origin_xz() const
{
if(size() > 1)
{
double min = DBL_MAX,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.y = 0;
d = origin | vertex;
if(d == 0.0)
return 0.0;
if(d < min)
min = d;
}
return min;
}
else
return 0.0;
}
//############################################################################
size_t LaserBoy_real_segment::i_min_distance_from_origin_xy() const
{
size_t index = 0;
if(size() > 1)
{
double min = DBL_MAX,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.z = 0;
d = origin | vertex;
if(d == 0.0)
return 0.0;
if(d < min)
{
index = i;
min = d;
}
}
}
return index;
}
//############################################################################
size_t LaserBoy_real_segment::i_min_distance_from_origin_zy() const
{
size_t index = 0;
if(size() > 1)
{
double min = DBL_MAX,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.x = 0;
d = origin | vertex;
if(d == 0.0)
return 0.0;
if(d < min)
{
index = i;
min = d;
}
}
}
return index;
}
//############################################################################
size_t LaserBoy_real_segment::i_min_distance_from_origin_xz() const
{
size_t index = 0;
if(size() > 1)
{
double min = DBL_MAX,
d;
LaserBoy_3D_double origin,
vertex;
for(size_t i = 0; i < size(); i++)
{
vertex = at(i);
vertex.y = 0;
d = origin | vertex;
if(d == 0.0)
return 0.0;
if(d < min)
{
index = i;
min = d;
}
}
}
return index;
}
//############################################################################
bool LaserBoy_real_segment::segment_passes_through_origin(const double& granularity) const
{
if(size() > 1)
{
LaserBoy_real_segment rs(*this);
rs.normalize_vectors_with_origin();
for(size_t i = 1; i < rs.size(); i++)
if(vector_passes_through_origin(at(i - 1), at(i), granularity))
return true;
}
return false;
}
//############################################################################
void LaserBoy_real_segment::blank_all_vertices()
{
if(size() > 1)
for(size_t i = 0; i < size(); i++)
at(i).blank();
return;
}
//############################################################################
void LaserBoy_real_segment::unblank_all_vertices()
{
if(size() > 1)
for(size_t i = 1; i < size(); i++)
at(i).unblank();
return;
}
//############################################################################
void LaserBoy_real_segment::strip_color() // to white in default palette
{
palette_index = LASERBOY_ILDA_DEFAULT;
if(size() > 1)
{
for(size_t i = 1; i < size(); i++)
if(at(i).is_color(p_space->black_level))
{
at(i).c = 55;
at(i).r = 255;
at(i).g = 255;
at(i).b = 255;
}
}
return;
}
//############################################################################
void LaserBoy_real_segment::strip_color_rgb(const LaserBoy_color& c)
{
palette_index = LASERBOY_TRUE_COLOR;
for(size_t i = 1; i < size(); i++)
{
if(at(i).is_color(p_space->black_level))
{
at(i).r = c.r;
at(i).g = c.g;
at(i).b = c.b;
}
}
sync_rgb_and_palette();
return;
}
//############################################################################
void LaserBoy_real_segment::index_hues(int index_multiple, int offset)
{
u_short hue_index = 0;
palette_index = LASERBOY_TRUE_COLOR;
for(size_t i = 1; i < size(); i += index_multiple)
{
for(int j = 0; j < index_multiple; j++)
{
if( (i + j) < size()
&& at(i + j).is_color(p_space->black_level)
)
{
hue_index = hue_index % 1530;
at(i + j) = LaserBoy_color(hue_index);
}
}
hue_index++;
}
return;
}
//############################################################################
void LaserBoy_real_segment::span_hues(double span_factor, int offset)
{
palette_index = LASERBOY_TRUE_COLOR;
if(size() > 1)
for(size_t i = 1; i < size(); i++)
if(at(i).is_color(p_space->black_level))
at(i) = LaserBoy_color((u_short)(((int)(((i * span_factor) / (double)(size() - 1)) * 1530) + offset) % 1530));
return;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::reverse()
{
if(size() > 1)
{
int i;
LaserBoy_real_segment reversed(palette_index, false);
LaserBoy_real_vertex vertex;
//----------------------------------------------------------------
reversed.reserve(size());
//----------------------------------------------------------------
i = size() - 1;
//----------------------------------------------------------------
vertex = at(i--);
vertex.blank();
reversed.push_back(vertex);
//----------------------------------------------------------------
while(i >= 0)
{
vertex = at(i );
vertex.r = at(i + 1).r;
vertex.g = at(i + 1).g;
vertex.b = at(i + 1).b;
vertex.c = at(i + 1).c;
vertex.k = at(i + 1).k;
reversed.push_back(vertex);
i--;
}
//----------------------------------------------------------------
*this = reversed;
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::reorder_from(size_t vertex_index)
{
if( vertex_index
&& vertex_index < size()
&& size() > 1
)
{
size_t i;
LaserBoy_real_segment reordered(palette_index, false);
//----------------------------------------------------------------
for(i = vertex_index; i < size(); i++)
reordered += at(i);
reordered.front().blank();
for(i = 0; i <= vertex_index; i++)
reordered += at(i);
*this = reordered;
//----------------------------------------------------------------
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::center_x()
{
if(size() > 1)
{
LaserBoy_3D_double center = rectangular_center_of();
for(size_t i = 0; i < size(); i++)
at(i).x = at(i).x - center.x;
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::center_y()
{
if(size() > 1)
{
LaserBoy_3D_double center = rectangular_center_of();
for(size_t i = 0; i < size(); i++)
at(i).y = at(i).y - center.y;
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::center_z()
{
if(size() > 1)
{
LaserBoy_3D_double center = rectangular_center_of();
for(size_t i = 0; i < size(); i++)
at(i).z = at(i).z - center.z;
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::center()
{
if(size() > 1)
{
LaserBoy_3D_double center = rectangular_center_of();
for(size_t i = 0; i < size(); i++)
at(i) = at(i) - center;
}
return *this;
}
//############################################################################
void LaserBoy_real_segment::flip(u_int plane)
{
if(size() > 1)
{
size_t i;
switch(plane)
{
case 0: // X mirror
for(i = 0; i < size(); i++)
at(i).x = -at(i).x;
break;
//-----------------------------------------------------------------
case 1: // Y flip
for(i = 0; i < size(); i++)
at(i).y = -at(i).y;
break;
//-----------------------------------------------------------------
case 2: // Z
for(i = 0; i < size(); i++)
at(i).z = -at(i).z;
break;
//-----------------------------------------------------------------
case 3: // X, Y
for(i = 0; i < size(); i++)
{
at(i).x = -at(i).x;
at(i).y = -at(i).y;
}
break;
//-----------------------------------------------------------------
case 4: // X, Y, Z
for(i = 0; i < size(); i++)
at(i) = -at(i);
break;
//-----------------------------------------------------------------
}
}
return;
}
//############################################################################
void LaserBoy_real_segment::quarter_turn(u_int plane, u_int turns)
{
if(size() > 1)
{
size_t i;
u_int j;
double temp;
switch(plane)
{
case 0: // X Y
for(i = 0; i < size(); i++)
for(j = 0; j < turns; j++)
{
temp = -at(i).x;
at(i).x = at(i).y;
at(i).y = temp;
}
break;
//-----------------------------------------------------------------
case 1: // Z Y
for(i = 0; i < size(); i++)
for(j = 0; j < turns; j++)
{
temp = -at(i).z;
at(i).z = at(i).y;
at(i).y = temp;
}
break;
//-----------------------------------------------------------------
case 2: // X Z
for(i = 0; i < size(); i++)
for(j = 0; j < turns; j++)
{
temp = -at(i).x;
at(i).x = at(i).z;
at(i).z = temp;
}
break;
//-----------------------------------------------------------------
}
}
return;
}
//############################################################################
void LaserBoy_real_segment::flatten_z()
{
if(size() > 1)
for(size_t i = 0; i < size(); i++)
at(i).z = 0;
return;
}
//############################################################################
double LaserBoy_real_segment::vector_angle(size_t vertex_index) const
{
double angle = 0.0;
if(vertex_index != 0)
{
if(size() > 1)
{
int _0 = 0,
_1 = 0,
_2 = 0;
//-----------------------------------------------------------------
if(vertex_index > 0 && vertex_index < size() - 1)
{
_0 = vertex_index - 1;
_1 = vertex_index ;
_2 = vertex_index + 1;
}
//-----------------------------------------------------------------
else if(vertex_index == size() - 1)
{
_0 = size() - 2;
_1 = 0 ;
_2 = 1 ;
}
//----------------------------------------------------------------
angle = delta_angle( at(_0) | at(_2), // distance between vertices 0,2
at(_0) | at(_1),
at(_1) | at(_2)
);
}
}
return angle;
}
//############################################################################
double LaserBoy_real_segment::total_angle() const
{
double total = 0.0;
size_t i;
if(size() > 1)
for(i = 0; i < size() - 1; i++)
total += vector_angle(i);
return total;
}
//############################################################################
double LaserBoy_real_segment::max_angle() const
{
double max = 0.0;
size_t i;
if(size() > 1)
for(i = 0; i < size() - 1; i++)
if(max < vector_angle(i))
max = vector_angle(i);
return max;
}
//############################################################################
double LaserBoy_real_segment::total_magnitude() const
{
double total = 0.0;
size_t i;
if(size() > 1)
for(i = 0; i < size() - 1; i++)
total += (at(i) | at(i + 1));
return total;
}
//############################################################################
double LaserBoy_real_segment::max_magnitude() const
{
double max = 0.0,
d;
size_t i;
if(size() > 1)
for(i = 0; i < size() - 1; i++)
{
d = (at(i) | at(i + 1));
if(max < d)
max = d;
}
return max;
}
//############################################################################
double LaserBoy_real_segment::max_color_magnitude() const
{
double max = 0.0,
d;
size_t i;
if(size() > 1)
for(i = 0; i < size() - 1; i++)
if(at(i + 1).is_color(p_space->black_level))
{
d = (at(i) | at(i + 1));
if(max < d)
max = d;
}
return max;
}
//############################################################################
double LaserBoy_real_segment::max_dark_magnitude() const
{
double max = 0.0,
d;
size_t i;
if(size() > 1)
for(i = 0; i < size() - 1; i++)
if(at(i + 1).is_dark(p_space->black_level))
{
d = (at(i) | at(i + 1));
if(max < d)
max = d;
}
return max;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::move_(LaserBoy_3D_double displacement,
double move_acceleration
)
{
if(size() > 1)
{
double step,
dsize = size() - 1.0;
if(move_acceleration == 0.0)
for(size_t i = 0; i < size(); i++)
at(i) += (displacement * (i / dsize));
else if(move_acceleration > 0.0)
{
step = move_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) += (displacement * (i / dsize) * pow(_e_, -(move_acceleration - (i * step))));
}
else // if(move_acceleration < 0.0)
{
move_acceleration = -move_acceleration;
step = move_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(dsize - i) += (displacement - (displacement * (i / dsize)) * pow(_e_, -(move_acceleration - (i * step))));
}
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::scale_(LaserBoy_3D_double factor, // from
LaserBoy_3D_double factor_, // to
double scale_acceleration
)
{
if( ( factor != 1.0
|| factor_ != 1.0
)
&& size() > 1
)
{
double step,
dsize = size() - 1.0;
LaserBoy_3D_double diff;
if(scale_acceleration == 0.0)
{
diff = factor_ - factor;
for(size_t i = 0; i < size(); i++)
at(i) *= (factor + (diff * (i / dsize)));
}
else if(scale_acceleration > 0.0)
{
diff = factor_ - factor;
step = scale_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) *= (factor + (diff * (i / dsize) * pow(_e_, -(scale_acceleration - (i * step)))));
}
else // if(scale_acceleration < 0.0)
{
diff = factor - factor_;
scale_acceleration = -scale_acceleration;
step = scale_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(dsize - i) *= (factor_ + (diff * (i / dsize) * pow(_e_, -(scale_acceleration - (i * step)))));
}
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::rotate_(LaserBoy_3D_double fulcrum,
LaserBoy_3D_double fulcrum_,
double fulcrum_acceleration,
LaserBoy_3D_double rotation,
double rotate_acceleration
)
{
double r_step,
f_step,
dsize = size() - 1.0;
LaserBoy_3D_double diff = fulcrum_ - fulcrum;
if(size() > 1 && rotation != 0.0)
{
if(fulcrum_acceleration == 0.0)
{
if(rotate_acceleration == 0.0)
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + diff * (i / dsize),
rotation * (i / dsize)
);
else if(rotate_acceleration > 0.0)
{
r_step = rotate_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + diff * (i / dsize),
rotation * (i / dsize) * pow(_e_, -(rotate_acceleration - (i * r_step)))
);
}
else // if(rotate_acceleration < 0.0)
{
rotate_acceleration = -rotate_acceleration;
r_step = rotate_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(dsize - i) = rotate_vertex_on_coordinates(at(dsize - i),
fulcrum + diff * (i / dsize),
rotation - (rotation * (i / dsize) * pow(_e_, -(rotate_acceleration - (i * r_step))))
);
}
} // end if(fulcrum_acceleration == 0.0)
else if(fulcrum_acceleration > 0.0)
{
if(rotate_acceleration == 0.0)
for(size_t i = 0; i < size(); i++)
{
f_step = fulcrum_acceleration / size();
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rotation * (i / dsize)
);
}
else if(rotate_acceleration > 0.0)
{
r_step = rotate_acceleration / size();
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rotation * (i / dsize) * pow(_e_, -(rotate_acceleration - (i * r_step)))
);
}
else // if(rotate_acceleration < 0.0)
{
rotate_acceleration = -rotate_acceleration;
r_step = rotate_acceleration / size();
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(dsize - i) = rotate_vertex_on_coordinates(at(dsize - i),
fulcrum + (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rotation - (rotation * (i / dsize) * pow(_e_, -(rotate_acceleration - (i * r_step))))
);
}
} // end else if(fulcrum_acceleration > 0.0)
else // (fulcrum_acceleration < 0.0)
{
if(rotate_acceleration == 0.0)
for(size_t i = 0; i < size(); i++)
{
fulcrum_acceleration = -fulcrum_acceleration;
f_step = fulcrum_acceleration / size();
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum_ - (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rotation * (i / dsize)
);
}
else if(rotate_acceleration > 0.0)
{
r_step = rotate_acceleration / size();
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum_ - (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rotation * (i / dsize) * pow(_e_, -(rotate_acceleration - (i * r_step)))
);
}
else // if(rotate_acceleration < 0.0)
{
fulcrum_acceleration = -fulcrum_acceleration;
rotate_acceleration = -rotate_acceleration;
f_step = fulcrum_acceleration / size();
r_step = rotate_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(dsize - i) = rotate_vertex_on_coordinates(at(dsize - i),
fulcrum_ - (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rotation - (rotation * (i / dsize) * pow(_e_, -(rotate_acceleration - (i * r_step))))
);
}
}
}
return *this;
}
//############################################################################
LaserBoy_real_vertex LaserBoy_real_segment::interpolated_value_at(double relative_position) const
{
LaserBoy_real_vertex value;
if( size() > 1
&& relative_position >= 0.0
&& relative_position <= 1.0
)
{
double location = relative_position * (size() - 1.0);
u_int from = (u_int)location,
to = from + 1;
if(to >= size())
to = size() - 1;
if(from >= size())
from = size() - 1;
value = at(from) + ((at(to) - at(from)) * (location - from));
if(at(from).is_lit() || at(to).is_lit())
value.unblank();
}
return value;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::add(LaserBoy_real_segment rs_displacements)
{
if( size() > 1
&& rs_displacements.size() > 1
)
{
if(size() == rs_displacements.size())
{
for(size_t i = 0; i < size(); i++)
at(i) += rs_displacements.at(i);
}
else if(size() > rs_displacements.size())
{
for(size_t i = 0; i < size(); i++)
at(i) += rs_displacements.interpolated_value_at((double)i / (size() - 1));
}
else
{
for(size_t i = 0; i < rs_displacements.size(); i++)
rs_displacements.at(i) = rs_displacements.at(i)
+ interpolated_value_at((double)i / (rs_displacements.size() - 1));
*this = rs_displacements;
}
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::multiply(LaserBoy_real_segment rs_factors)
{
if( size() > 1
&& rs_factors.size() > 1
)
{
if(size() == rs_factors.size())
{
for(size_t i = 0; i < size(); i++)
at(i) *= rs_factors.at(i);
}
else if(size() > rs_factors.size())
{
for(size_t i = 0; i < size(); i++)
at(i) *= rs_factors.interpolated_value_at((double)i / (size() - 1));
}
else
{
for(size_t i = 0; i < rs_factors.size(); i++)
rs_factors.at(i) *= interpolated_value_at((double)i / (rs_factors.size() - 1));
*this = rs_factors;
}
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::warp(LaserBoy_3D_double fulcrum,
LaserBoy_3D_double fulcrum_,
double fulcrum_acceleration,
LaserBoy_real_segment rs_rotations
)
{
double f_step,
dsize;
LaserBoy_3D_double diff = fulcrum_ - fulcrum;
LaserBoy_real_segment rs;
if( size() > 1
&& rs_rotations.size() > 1
)
{
if(fulcrum_acceleration == 0)
{
if(size() == rs_rotations.size())
{
dsize = size() - 1;
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + diff * (i / dsize),
rs_rotations.at(i) * pi
);
}
else if(size() > rs_rotations.size())
{
dsize = size() - 1;
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + diff * (i / dsize),
rs_rotations.interpolated_value_at(i / dsize) * pi
);
}
else // (size() < rs_rotations.size())
{
dsize = rs_rotations.size() - 1;
for(size_t i = 0; i < rs_rotations.size(); i++)
rs_rotations.at(i) = rotate_vertex_on_coordinates(interpolated_value_at(i / dsize),
fulcrum + diff * (i / dsize),
rs_rotations.at(i) * pi
);
*this = rs_rotations;
}
}
else if(fulcrum_acceleration > 0.0)
{
if(size() == rs_rotations.size())
{
dsize = size() - 1;
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rs_rotations.at(i) * pi
);
}
else if(size() > rs_rotations.size())
{
dsize = size() - 1;
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rs_rotations.interpolated_value_at(i / dsize) * pi
);
}
else // (size() < rs_rotations.size())
{
dsize = rs_rotations.size() - 1;
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < rs_rotations.size(); i++)
rs_rotations.at(i) = rotate_vertex_on_coordinates(interpolated_value_at(i / dsize),
fulcrum + (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rs_rotations.at(i) * pi
);
*this = rs_rotations;
}
}
else
{
fulcrum_acceleration = -fulcrum_acceleration;
if(size() == rs_rotations.size())
{
dsize = size() - 1;
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum_ - (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rs_rotations.at(i) * pi
);
}
else if(size() > rs_rotations.size())
{
dsize = size() - 1;
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum_ - (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rs_rotations.interpolated_value_at(i / dsize) * pi
);
}
else // (size() < rs_rotations.size())
{
dsize = rs_rotations.size() - 1;
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < rs_rotations.size(); i++)
rs_rotations.at(i) = rotate_vertex_on_coordinates(interpolated_value_at(i / dsize),
fulcrum_ - (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rs_rotations.at(i) * pi
);
*this = rs_rotations;
}
}
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::xyz_rgb(LaserBoy_real_segment rs_colors)
{
palette_index = LASERBOY_TRUE_COLOR;
if( size() > 1
&& rs_colors.size() > 1
)
{
if(size() == rs_colors.size())
{
for(size_t i = 0; i < size(); i++)
{
at(i).r = (char)(255 * (rs_colors.at(i).x + 1.0) / 2.0);
at(i).g = (char)(255 * (rs_colors.at(i).y + 1.0) / 2.0);
at(i).b = (char)(255 * (rs_colors.at(i).z + 1.0) / 2.0);
}
}
else if(size() > rs_colors.size())
{
double dsize = size() - 1;
for(size_t i = 0; i < size(); i++)
{
at(i).r = (char)(255 * (rs_colors.interpolated_value_at(i / dsize).x + 1.0) / 2.0);
at(i).g = (char)(255 * (rs_colors.interpolated_value_at(i / dsize).y + 1.0) / 2.0);
at(i).b = (char)(255 * (rs_colors.interpolated_value_at(i / dsize).z + 1.0) / 2.0);
}
}
else
{
for(size_t i = 0; i < rs_colors.size(); i++)
{
rs_colors.at(i) = interpolated_value_at((double)i / (rs_colors.size() - 1));
rs_colors.at(i).r = (char)(255 * (rs_colors.at(i).x + 1.0) / 2.0);
rs_colors.at(i).g = (char)(255 * (rs_colors.at(i).y + 1.0) / 2.0);
rs_colors.at(i).b = (char)(255 * (rs_colors.at(i).z + 1.0) / 2.0);
}
*this = rs_colors;
}
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::to_polar()
{
for(size_t i = 0; i < size(); i++)
at(i) = LaserBoy_3D_double(at(i).y * cos(at(i).x),
at(i).y * sin(at(i).x),
at(i).z
);
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::differences()
{
LaserBoy_real_segment rs;
rs.push_back(at(0));
for(size_t i = 1; i < size(); i++)
rs.push_back(at(i) - at(i - 1));
*this = rs;
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::sums()
{
LaserBoy_real_segment rs;
rs.push_back(at(0));
for(size_t i = 1; i < size(); i++)
{
rs.push_back(rs.back() + at(i));
rs.back().unblank();
}
*this = rs;
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::to_rectangular()
{ // this doesn't work!
/*
LaserBoy_real_segment rectangular;
if(size() > 1)
{
u_int i,
least = 0;
double rho,
theta,
diff,
diff_a,
diff_b,
diff_c,
diff_d,
min = DBL_MAX;
LaserBoy_real_vertex a,
b,
c,
d;
for(i = 0; i < size(); i++)
{
rho = sqrt(at(i).x * at(i).x + at(i).y * at(i).y);
theta = atan2(at(i).y, at(i).x);
if(theta < 0.0)
theta += two_pi;
rectangular.push_back(LaserBoy_real_vertex(theta,
rho,
at(i).z,
at(i).r,
at(i).g,
at(i).b,
at(i).k,
at(i).c
)
);
}
for(i = 1; i < size(); i++)
{
a = rectangular.at(i);
a.x -= pi;
a.y = -a.y;
a.z = 0;
b = rectangular.at(i);
b.x += pi;
b.y = -b.y;
b.z = 0;
c = rectangular.at(i);
c.x += two_pi;
c.z = 0;
d = rectangular.at(i);
d.x += (pi * 3);
d.y = -d.y;
d.z = 0;
diff = rectangular.at(i - 1) | rectangular.at(i);
diff_a = rectangular.at(i - 1) | a;
diff_b = rectangular.at(i - 1) | b;
diff_c = rectangular.at(i - 1) | c;
diff_d = rectangular.at(i - 1) | d;
if(diff < min)
{
min = diff;
least = 0;
}
if(diff_a < min)
{
min = diff_a;
least = 1;
}
if(diff_b < min)
{
min = diff_b;
least = 2;
}
if(diff_c < min)
{
min = diff_c;
least = 3;
}
if(diff_d < min)
{
min = diff_d;
least = 4;
}
switch(least)
{
case 0:
break;
case 1:
rectangular.at(i).x = a.x;
rectangular.at(i).y = a.y;
break;
case 2:
rectangular.at(i).x = b.x;
rectangular.at(i).y = b.y;
break;
case 3:
rectangular.at(i).x = c.x;
rectangular.at(i).y = c.y;
break;
case 4:
rectangular.at(i).x = d.x;
rectangular.at(i).y = d.y;
break;
}
}
}
*/
return *this;
}
//############################################################################
void LaserBoy_real_segment::rotate(LaserBoy_3D_double a)
{
if(size() > 1)
{
LaserBoy_3D_double center = centroid_of_coordinates();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i), center, a);
}
return;
}
//############################################################################
void LaserBoy_real_segment::rotate_around_origin(LaserBoy_3D_double a)
{
if(size() > 1)
{
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex(at(i), a);
}
return;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::rotate_on_coordinates(LaserBoy_3D_double fulcrum,
LaserBoy_3D_double fulcrum_,
double fulcrum_acceleration,
LaserBoy_3D_double rotation
)
{
if(size() > 1)
{
double f_step,
dsize = size() - 1.0;
LaserBoy_3D_double diff = fulcrum_ - fulcrum;
if(fulcrum_acceleration == 0.0)
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + (diff * (i / dsize)),
rotation
);
else if(fulcrum_acceleration > 0.0)
{
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum + (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rotation
);
}
else // (fulcrum_acceleration < 0.0)
{
fulcrum_acceleration = -fulcrum_acceleration;
f_step = fulcrum_acceleration / size();
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates(at(i),
fulcrum_ - (diff * (i / dsize) * pow(_e_, -(fulcrum_acceleration - (i * f_step)))),
rotation
);
}
}
return *this;
}
//############################################################################
void LaserBoy_real_segment::rotate_on_coordinates_x(LaserBoy_3D_double p, double a)
{
if(size() > 1)
{
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates_x(at(i), p, a);
}
return;
}
//############################################################################
void LaserBoy_real_segment::rotate_on_coordinates_y(LaserBoy_3D_double p, double a)
{
if(size() > 1)
{
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates_y(at(i), p, a);
}
return;
}
//############################################################################
void LaserBoy_real_segment::rotate_on_coordinates_z(LaserBoy_3D_double p, double a)
{
if(size() > 1)
{
for(size_t i = 0; i < size(); i++)
at(i) = rotate_vertex_on_coordinates_z(at(i), p, a);
}
return;
}
//############################################################################
bool LaserBoy_real_segment::find_rgb_in_palette(const LaserBoy_palette& palette)
{
bool all_colors_found = true;
if(size() > 1)
{
size_t i,
j;
vector match(size(), false);
//--------------------------------------------------------------------
for(i = 0; i < size(); i++)
for(j = 0; j < palette.number_of_colors(); j++)
if((LaserBoy_color)at(i) == palette.at(j))
{
at(i).c = (u_char)j;
match[i] = true;
}
//--------------------------------------------------------------------
for(i = 0; i < size(); i++)
all_colors_found &= match[i];
//--------------------------------------------------------------------
}
return all_colors_found;
}
//############################################################################
void LaserBoy_real_segment::promote_to_true_color()
{
if(palette_index != LASERBOY_TRUE_COLOR)
{
set_rgb_from_palette();
palette_index = LASERBOY_TRUE_COLOR;
}
return;
}
//############################################################################
void LaserBoy_real_segment::set_rgb_from_palette()
{
if( palette_index != LASERBOY_TRUE_COLOR
&& size() > 1
)
for(size_t i = 0; i < size(); i++)
{
if(at(i).is_color(p_space->black_level))
{
at(i).r = p_space->palette_picker(palette_index)[at(i).c].r;
at(i).g = p_space->palette_picker(palette_index)[at(i).c].g;
at(i).b = p_space->palette_picker(palette_index)[at(i).c].b;
}
else if(at(i).is_black(p_space->black_level))
{
at(i).r = 0;
at(i).g = 0;
at(i).b = 0;
}
}
return;
}
//############################################################################
void LaserBoy_real_segment::set_palette_to_332()
{
if(size() > 1)
{
front().c = 0x00;
for(size_t i = 1; i < size(); i++)
at(i).c = (at(i).r & 0xe0)
| ((at(i).g & 0xe0) >> 3)
| ((at(i).b & 0xc0) >> 6);
// does NOT set palette_index to LASERBOY_REDUCED_332
}
return;
}
//############################################################################
void LaserBoy_real_segment::sync_rgb_and_palette()
{
if(size() > 1)
{
bool fits_in_default = true;
int i;
if(palette_index != LASERBOY_TRUE_COLOR)
{
for(i = 0; i < (int)p_space->palette_picker(palette_index).size(); i++)
fits_in_default &= p_space->palette_picker(LASERBOY_ILDA_DEFAULT).has_color(p_space->palette_picker(palette_index).at(i));
if(fits_in_default)
{
best_match_palette(LASERBOY_ILDA_DEFAULT);
return;
}
set_rgb_from_palette();
return;
}
//----------------------------------------------------------------
size_t j;
LaserBoy_palette palette,
reordered;
//----------------------------------------------------------------
if(first_lit_vector_index() > -1) // there are lit vectors!
{
palette.push_back((LaserBoy_color)at(first_lit_vector_index()));
//----------------------------------------------------------------
for(i = first_lit_vector_index() + 1; i < (int)size(); i++)
{
for(j = 0; j < palette.number_of_colors(); j++)
if(at(i).is_lit() && (palette[j] == (LaserBoy_color)at(i)))
break;
if( j == palette.number_of_colors()
&& at(i).is_lit()
)
palette.push_back((LaserBoy_color)at(i));
if(palette.number_of_colors() > LASERBOY_PALETTE_MAX)
{
set_palette_to_332();
return;
}
}
//----------------------------------------------------------------
for(i = 0; i < (int)palette.size(); i++)
fits_in_default &= p_space->palette_picker(LASERBOY_ILDA_DEFAULT).has_color(palette.at(i));
if(fits_in_default)
{
best_match_palette(LASERBOY_ILDA_DEFAULT);
return;
}
palette.reorder();
for(i = p_space->number_of_palettes() - 1; i >= 0; i--)
{
reordered = p_space->palette_picker(i);
reordered.reorder();
if(palette.is_in(reordered))
{
palette_index = i;
find_rgb_in_palette(p_space->palette_picker(i));
return;
}
}
palette.find_factors();
find_rgb_in_palette(palette);
palette.name = GUID8char();
p_space->push_back_palette(palette);
palette_index = p_space->number_of_palettes() - 1;
return;
} // end if(first_lit_vector_index() > -1) // there are lit vectors!
palette_index = LASERBOY_ILDA_DEFAULT;
//----------------------------------------------------------------
} // end if(size() > 1)
return;
}
//############################################################################
void LaserBoy_real_segment::best_match_palette(int index)
{
if( index != palette_index
&& index < p_space->number_of_palettes()
)
{
if(size() > 1)
{
if(!p_space->allow_lit_black)
convert_black_to_blank();
else
impose_black_level();
for(size_t i = 1; i < size(); i++)
at(i).c = p_space->
palette_picker(index)
.best_match(at(i));
}
palette_index = index;
set_rgb_from_palette();
p_space->palette_index = palette_index;
}
return;
}
//############################################################################
void LaserBoy_real_segment::bit_reduce_to_palette()
{
if(palette_index == LASERBOY_TRUE_COLOR)
{
set_palette_to_332();
palette_index = LASERBOY_REDUCED_332;
set_rgb_from_palette();
}
return;
}
//############################################################################
void LaserBoy_real_segment::best_reduce_to_palette()
{
if(number_of_color_vectors() >= 1)
{
int local_palette_index;
size_t i,
j;
LaserBoy_palette palette;
//----------------------------------------------------------------
if(!p_space->allow_lit_black)
convert_black_to_blank();
else
impose_black_level();
//----------------------------------------------------------------
palette.push_back((LaserBoy_color)at(first_lit_vector_index()));
//----------------------------------------------------------------
for(i = first_lit_vector_index() + 1; i < size(); i++)
{
for(j = 0; j < palette.number_of_colors(); j++)
if(at(i).is_lit() && (palette[j] == (LaserBoy_color)at(i)))
break;
if( j == palette.number_of_colors()
&& at(i).is_lit()
)
palette.push_back((LaserBoy_color)at(i));
}
//----------------------------------------------------------------
local_palette_index = palette.best_reduction();
if(local_palette_index == -1)
{
palette.name = GUID8char();
p_space->push_back_palette(palette);
best_match_palette(p_space->number_of_palettes() - 1);
}
else
best_match_palette(local_palette_index);
//----------------------------------------------------------------
}
return;
}
//############################################################################
void LaserBoy_real_segment::convert_black_to_blank()
{
if(size() > 1)
for(size_t i = 1; i < size(); i++)
{
if(at(i).is_black(p_space->black_level))
{
at(i).r = 255;
at(i).g = 0;
at(i).b = 0;
at(i).c = 0;
at(i).blank();
}
}
return;
}
//############################################################################
void LaserBoy_real_segment::convert_blank_to_black()
{
if(size() > 1)
for(size_t i = 1; i < size(); i++)
{
if(at(i).is_blank())
{
at(i).r = 0;
at(i).g = 0;
at(i).b = 0;
at(i).c = p_space->palette_picker(palette_index).black;
at(i).unblank();
}
}
return;
}
//############################################################################
void LaserBoy_real_segment::impose_black_level()
{
if(size() > 1)
for(size_t i = 1; i < size(); i++)
{
if(at(i).as_color().average() < p_space->black_level)
{
at(i).r = 0;
at(i).g = 0;
at(i).b = 0;
}
}
return;
}
//############################################################################
void LaserBoy_real_segment::reduce_blank_vectors()
{
if(size() > 1)
{
size_t i;
LaserBoy_real_segment minimum_blanking(palette_index, false);
minimum_blanking.push_back(front());
minimum_blanking.back().blank();
for(i = 1; i < size(); i++)
{
if( at(i).is_blank()
&& minimum_blanking.back().is_blank()
)
minimum_blanking.back() = at(i); // the new, last blank
else
minimum_blanking.push_back(at(i));
}
while(minimum_blanking.size() && minimum_blanking.back().is_blank())
minimum_blanking.pop_back();
*this = minimum_blanking;
}
return;
}
//############################################################################
void LaserBoy_real_segment::reduce_lit_vectors()
{
if(size() > 1)
{
size_t i;
LaserBoy_real_segment segment_1(palette_index, false),
segment_2(palette_index, false);
//----------------------------------------------------------------
segment_1.reserve(size());
segment_2.reserve(size());
//----------------------------------------------------------------
segment_1.push_back(front());
for(i = 1; i < size(); i++)
{
if(at(i) != segment_1.back())
segment_1.push_back(at(i));
}
//----------------------------------------------------------------
while(segment_1.size() && segment_1.back().is_blank())
segment_1.pop_back();
//----------------------------------------------------------------
if(segment_1.size())
{
segment_2.push_back(segment_1.front());
for(i = 1; i < segment_1.size() - 1; i++)
{
if( ( segment_1.at(i ).color_of(p_space->black_level)
!= segment_1.at(i + 1).color_of(p_space->black_level)
)
|| ( segment_1.vector_angle(i)
> p_space->insignificant_angle
)
)
segment_2.push_back(segment_1.at(i));
}
//----------------------------------------------------------------
segment_2.push_back(segment_1.at(i));
while(segment_2.size() && segment_2.back().is_blank())
segment_2.pop_back();
}
//----------------------------------------------------------------
*this = segment_2;
}
return;
}
//############################################################################
void LaserBoy_real_segment::omit_equivalent_vectors()
{
if(number_of_segments() > 1)
{
LaserBoy_real_segment_set segments;
size_t i,
j;
//----------------------------------------------------------------
reduce_blank_vectors();
reduce_lit_vectors();
fracture_segments();
segments = explode_segments();
//----------------------------------------------------------------
for(i = 0; i < segments.size() - 1; i++)
{
for(j = i + 1; j < segments.size(); j++)
if( segments[i] == segments[j]
|| segments[i] == segments[j].reverse()
)
segments[j].clear();
}
//----------------------------------------------------------------
*this = segments.sum_of_frames();
//----------------------------------------------------------------
}
return;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::move(LaserBoy_3D_double d)
{
if(size() > 1)
for(size_t i = 0; i < size(); i++)
at(i) += d;
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::scale_around_origin(LaserBoy_3D_double s)
{
if(size() > 1)
for(size_t i = 0; i < size(); i++)
at(i) *= s;
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::scale_on_coordinates(LaserBoy_3D_double p, LaserBoy_3D_double s)
{
if(size() > 1)
for(size_t i = 0; i < size(); i++)
at(i) = ((at(i).as_3D_double() - p) * s) + p;
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::scale(LaserBoy_3D_double s)
{
return scale_on_coordinates(centroid_of_coordinates(), s);
}
//############################################################################
LaserBoy_Error_Code LaserBoy_real_segment::add_lit_span_vertices()
{
if(size() > 1)
{
size_t i;
LaserBoy_real_segment distance_optimized(palette_index, false),
line (palette_index, false);
//----------------------------------------------------------------
for(i = 0; i < (size() - 1); i++)
{
distance_optimized.push_back(at(i));
if( at(i + 1).is_lit()
&& (at(i) | at(i + 1)) > p_space->lit_delta_max
)
{
line += LaserBoy_real_segment(at(i), at(i + 1));
line.pop_back();
distance_optimized += line;
line.clear();
}
}
distance_optimized.push_back(back());
//----------------------------------------------------------------
*this = distance_optimized;
}
return real_segment_error;
}
//############################################################################
void LaserBoy_real_segment::add_lit_span_vertices(const u_int& max_d)
{
if(size() > 1)
{
size_t i;
LaserBoy_real_segment distance_optimized(palette_index, false),
line (palette_index, false);
//----------------------------------------------------------------
for(i = 0; i < (size() - 1); i++)
{
distance_optimized.push_back(at(i));
if( at(i + 1).is_lit()
&& (at(i) | at(i + 1)) > max_d
)
{
line += LaserBoy_real_segment(at(i), at(i + 1), max_d);
line.pop_back();
distance_optimized += line;
line.clear();
}
}
distance_optimized.push_back(back());
*this = distance_optimized;
}
return;
}
//############################################################################
LaserBoy_Error_Code LaserBoy_real_segment::add_blank_span_vertices()
{
if(size() > 1)
{
size_t i;
LaserBoy_real_segment distance_optimized(palette_index, false),
line (palette_index, false);
//----------------------------------------------------------------
for(i = 0; i < (size() - 1); i++)
{
distance_optimized.push_back(at(i));
if( at(i + 1).is_blank()
&& (at(i) | at(i + 1)) > p_space->blank_delta_max
)
{
line += LaserBoy_real_segment(at(i), at(i + 1));
line.pop_back();
distance_optimized += line;
line.clear();
}
}
distance_optimized.push_back(back());
//----------------------------------------------------------------
*this = distance_optimized;
}
return real_segment_error;
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::rectangular_center_of() const
{
LaserBoy_3D_double center;
if(size() > 1)
{
double max_x = -DBL_MAX,
min_x = DBL_MAX,
max_y = -DBL_MAX,
min_y = DBL_MAX,
max_z = -DBL_MAX,
min_z = DBL_MAX;
for(size_t i = 0; i < size(); i++)
{
if(at(i).x > max_x) max_x = at(i).x;
if(at(i).x < min_x) min_x = at(i).x;
if(at(i).y > max_y) max_y = at(i).y;
if(at(i).y < min_y) min_y = at(i).y;
if(at(i).z > max_z) max_z = at(i).z;
if(at(i).z < min_z) min_z = at(i).z;
}
center.x = (max_x - ((max_x - min_x) / 2.0));
center.y = (max_y - ((max_y - min_y) / 2.0));
center.z = (max_z - ((max_z - min_z) / 2.0));
}
return center;
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::mean_of_coordinates() const
{
LaserBoy_3D_double mean;
if(size() > 1)
{
mean = front();
for(size_t i = 1; i < size(); i++)
mean += at(i);
mean /= size();
}
return mean;
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::centroid_of_coordinates_xy(double& area, LaserBoy_real_segment& rs) const
{
LaserBoy_3D_double centroid;
area = 0.0;
rs.clear();
if(size() > 1)
{
size_t i;
rs = polygon_outline_xy(area);
if(area == 0.0) // from this perspective the segment is either a dot or a line
return centroid;
for(i = 0; i < rs.size() - 1; i++)
{
centroid.x += (rs.at(i).x + rs.at(i + 1).x) * ((rs.at(i).x * rs.at(i + 1).y) - (rs.at(i + 1).x * rs.at(i).y));
centroid.y += (rs.at(i).y + rs.at(i + 1).y) * ((rs.at(i).x * rs.at(i + 1).y) - (rs.at(i + 1).x * rs.at(i).y));
}
centroid *= (1.0 / (area * 6.0));
return centroid;
}
return centroid;
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::centroid_of_coordinates_zy(double& area, LaserBoy_real_segment& rs) const
{
LaserBoy_3D_double centroid;
area = 0.0;
rs.clear();
if(size() > 1)
{
size_t i;
rs = polygon_outline_zy(area);
if(area == 0.0) // from this perspective the segment is either a dot or a line
return centroid;
for(i = 0; i < rs.size() - 1; i++)
{
centroid.z += (rs.at(i).z + rs.at(i + 1).z) * ((rs.at(i).z * rs.at(i + 1).y) - (rs.at(i + 1).z * rs.at(i).y));
centroid.y += (rs.at(i).y + rs.at(i + 1).y) * ((rs.at(i).z * rs.at(i + 1).y) - (rs.at(i + 1).z * rs.at(i).y));
}
centroid *= (1.0 / (area * 6.0));
return centroid;
}
return centroid;
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::centroid_of_coordinates_xz(double& area, LaserBoy_real_segment& rs) const
{
LaserBoy_3D_double centroid;
area = 0.0;
rs.clear();
if(size() > 1)
{
size_t i;
rs = polygon_outline_xz(area);
if(area == 0.0) // from this perspective the segment is either a dot or a line
return centroid;
for(i = 0; i < rs.size() - 1; i++)
{
centroid.x += (rs.at(i).x + rs.at(i + 1).x) * ((rs.at(i).x * rs.at(i + 1).z) - (rs.at(i + 1).x * rs.at(i).z));
centroid.z += (rs.at(i).z + rs.at(i + 1).z) * ((rs.at(i).x * rs.at(i + 1).z) - (rs.at(i + 1).x * rs.at(i).z));
}
centroid *= (1.0 / (area * 6.0));
return centroid;
}
return centroid;
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::centroid_of_coordinates() const
{
LaserBoy_real_segment rs(*this);
rs.reduce_blank_vectors();
rs.strip_color();
rs.reduce_lit_vectors();
LaserBoy_3D_double centroid = rs.rectangular_center_of();
if((rs.size() > 2) && rs.max_dimension())
{
double area_xy,
area_xz,
area_zy;
LaserBoy_real_segment polygon_xy,
polygon_xz,
polygon_zy;
LaserBoy_3D_double centroid_xy = rs.centroid_of_coordinates_xy(area_xy, polygon_xy),
centroid_xz = rs.centroid_of_coordinates_xz(area_xz, polygon_xz),
centroid_zy = rs.centroid_of_coordinates_zy(area_zy, polygon_zy);
if(area_xy != 0.0 || area_xz != 0.0)
centroid.x = ( centroid_xy.x * area_xy
+ centroid_xz.x * area_xz
)
/ (area_xy + area_xz);
if(area_xy != 0.0 || area_zy != 0.0)
centroid.y = ( centroid_xy.y * area_xy
+ centroid_zy.y * area_zy
)
/ (area_xy + area_zy);
if(area_zy != 0.0 || area_xz != 0.0)
centroid.z = ( centroid_zy.z * area_zy
+ centroid_xz.z * area_xz
)
/ (area_zy + area_xz);
}
return centroid;
}
//############################################################################
LaserBoy_real_segment LaserBoy_real_segment::polygon_outline_xy(double& area) const
{
LaserBoy_real_segment rs;
area = 0.0;
if((width() == 0.0) || (height() == 0.0))
return rs;
if(size() > 2)
{
bool cancave_found;
size_t i,
j;
LaserBoy_3D_double origin,
center;
rs = (*this);
for(i = 0; i < rs.size(); i++)
rs.at(i).z = 0.0; // 2D
rs.reduce_blank_vectors();
rs.strip_color();
rs.reduce_lit_vectors();
if(rs.size() < 3)
{
rs.clear();
return rs;
}
for(i = 0; i < rs.size(); i++)
rs.at(i).unblank();
center = rs.rectangular_center_of();
rs -= center;
rs.sort_by_rotation_xy();
rs.reorder_from(rs.i_max_distance_from_origin_xy());
rs.push_back(rs.front());
do
{
cancave_found = false;
for(i = 0; i < rs.size() - 2; i++)
if(three_point_angle_xy(rs.at(i + 1), rs.at(i), rs.at(i + 2)) <= pi)
{
cancave_found = true;
rs.remove_vertex(i + 1);
break;
}
} while(cancave_found == true);
if(rs.back().as_3D_double() == rs.front().as_3D_double())
rs.pop_back();
rs.sort_by_rotation_xy();
rs.push_back(rs.front());
rs.front().blank();
j = rs.size() - 2;
for(i = 0; i < rs.size() - 1; i++)
{
area += (rs.at(j).x + rs.at(i).x)
* (rs.at(j).y - rs.at(i).y);
j = i;
}
area = abs(area / 2.0);
if(area != 0.0)
return rs + center;
return LaserBoy_real_segment();
}
return rs;
}
//############################################################################
LaserBoy_real_segment LaserBoy_real_segment::polygon_outline_zy(double& area) const
{
LaserBoy_real_segment rs;
area = 0.0;
if((height() == 0.0) || (depth() == 0.0))
return rs;
if(size() > 2)
{
bool cancave_found;
size_t i,
j;
LaserBoy_3D_double origin,
center;
rs = (*this);
for(i = 0; i < rs.size(); i++)
rs.at(i).x = 0.0; // 2D
rs.reduce_blank_vectors();
rs.strip_color();
rs.reduce_lit_vectors();
if(rs.size() < 3)
{
rs.clear();
return rs;
}
for(i = 0; i < rs.size(); i++)
rs.at(i).unblank();
center = rs.rectangular_center_of();
rs -= center;
rs.sort_by_rotation_zy();
rs.reorder_from(rs.i_max_distance_from_origin_zy());
rs.push_back(rs.front());
do
{
cancave_found = false;
for(i = 0; i < rs.size() - 2; i++)
if(three_point_angle_zy(rs.at(i + 1), rs.at(i), rs.at(i + 2)) <= pi)
{
cancave_found = true;
rs.remove_vertex(i + 1);
break;
}
} while(cancave_found == true);
if(rs.back().as_3D_double() == rs.front().as_3D_double())
rs.pop_back();
rs.sort_by_rotation_zy();
rs.push_back(rs.front());
rs.front().blank();
j = rs.size() - 2;
for(i = 0; i < rs.size() - 1; i++)
{
area += (rs.at(j).z + rs.at(i).z)
* (rs.at(j).y - rs.at(i).y);
j = i;
}
area = abs(area / 2.0);
if(area != 0.0)
return rs + center;
return LaserBoy_real_segment();
}
return rs;
}
//############################################################################
LaserBoy_real_segment LaserBoy_real_segment::polygon_outline_xz(double& area) const
{
LaserBoy_real_segment rs;
area = 0.0;
if((width() == 0.0) || (depth() == 0.0))
return rs;
if(size() > 2)
{
bool cancave_found;
size_t i,
j;
LaserBoy_3D_double origin,
center;
rs = (*this);
for(i = 0; i < rs.size(); i++)
rs.at(i).y = 0.0; // 2D
rs.reduce_blank_vectors();
rs.strip_color();
rs.reduce_lit_vectors();
if(rs.size() < 3)
{
rs.clear();
return rs;
}
for(i = 0; i < rs.size(); i++)
rs.at(i).unblank();
center = rs.rectangular_center_of();
rs -= center;
rs.sort_by_rotation_xz();
rs.reorder_from(rs.i_max_distance_from_origin_xz());
rs.push_back(rs.front());
do
{
cancave_found = false;
for(i = 0; i < rs.size() - 2; i++)
if(three_point_angle_xz(rs.at(i + 1), rs.at(i), rs.at(i + 2)) <= pi)
{
cancave_found = true;
rs.remove_vertex(i + 1);
break;
}
} while(cancave_found == true);
if(rs.back().as_3D_double() == rs.front().as_3D_double())
rs.pop_back();
rs.sort_by_rotation_xz();
rs.push_back(rs.front());
rs.front().blank();
j = rs.size() - 2;
for(i = 0; i < rs.size() - 1; i++)
{
area += (rs.at(j).x + rs.at(i).x)
* (rs.at(j).z - rs.at(i).z);
j = i;
}
area = abs(area / 2.0);
if(area != 0.0)
return rs + center;
return LaserBoy_real_segment();
}
return rs;
}
//############################################################################
size_t LaserBoy_real_segment::number_of_segments() const // a segment is a series of lit verticies
{
size_t i,
segment_count = 0;
if(size() > 1)
{
for(i = 1; i < size(); i++)
{
if(at(i).is_lit())
{
while(at(i).is_lit() && i < (size() - 1))
i++;
segment_count++;
}
}
}
return segment_count;
}
//############################################################################
bool LaserBoy_real_segment::find_segment_at_index(size_t segment_index, size_t& start, size_t& end) const
{ // the first segment is number zero!
if(size() > 1)
{
size_t i;
int segment_count = -1;
//----------------------------------------------------------------
for(i = 1; i < size(); i++)
{
if(at(i).is_lit())
{
start = i - 1;
while(at(i).is_lit() && i < (size() - 1))
i++;
//------------------------------------------------------------
end = i - 1;
if( i == (size() - 1)
&& at(i).is_lit()
)
end = i;
//------------------------------------------------------------
segment_count++;
if(segment_count == (int)segment_index)
return true;
}
} // segment index either negative or out of range
//----------------------------------------------------------------
for(i = 1; i < size(); i++)
{
if(at(i).is_lit())
{
start = i - 1;
while(at(i).is_lit() && i < (size() - 1))
i++;
end = i - 1;
if( i == (size() - 1)
&& at(i).is_lit()
)
end = i;
//------------------------------------------------------------
return false; // and set start, end to first segment
}
}
}
//------------------------------------------------------------------------
return false;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::fracture_segments()
{
if(number_of_lit_vectors() > 1)
{
size_t i;
LaserBoy_real_segment fractured(palette_index, false);
fractured.reserve(3 * size());
reduce_blank_vectors();
//----------------------------------------------------------------
for(i = 0; i < size(); i++)
{
fractured.push_back(at(i));
fractured.push_back(at(i));
fractured.back().blank();
}
//----------------------------------------------------------------
fractured.pop_back();
fractured.reduce_blank_vectors();
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::bond_segments()
{
if(size() > 1)
{
size_t i;
LaserBoy_real_segment bonded(palette_index, false);
//----------------------------------------------------------------
bonded.reserve(size());
bonded.push_back(front());
for(i = 1; i < size() - 1; i++)
{
if( !( at(i).is_blank()
&& ( at(i)
| at(i - 1)
)
<= p_space->insignificant_distance
) )
bonded += at(i);
}
bonded.push_back(back());
//----------------------------------------------------------------
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::conglomerate_lit_segments()
{
if(number_of_segments() > 1)
{
bool match_found = false;
int i,
j,
least_angle_index;
double angle,
least_angle;
vector match_index;
vector match_index_type;
LaserBoy_real_segment copy(*this);
LaserBoy_real_segment rs(palette_index, false);
LaserBoy_real_segment_set lit_vectors;
//----------------------------------------------------------------
// copy.fracture_segments();
copy.reduce_blank_vectors();
copy.reduce_lit_vectors();
lit_vectors = copy.explode_segments();
// lit_vectors.reduce_blank_vectors ();
// lit_vectors.reduce_lit_vectors ();
// lit_vectors.omit_equivalent_vectors ();
//----------------------------------------------------------------
do
{
for(i = 0; i < (int)lit_vectors.number_of_frames(); i++)
{
match_found = false;
match_index.clear();
match_index_type.clear();
for(j = i + 1; j < (int)lit_vectors.number_of_frames(); j++)
{
if( lit_vectors[i].last_lit_vector().as_3D_double()
== lit_vectors[j].first_lit_anchor().as_3D_double()
)
{
match_found = true;
match_index_type.push_back('a');
match_index.push_back(j);
}
else if( lit_vectors[i].last_lit_vector().as_3D_double()
== lit_vectors[j].last_lit_vector().as_3D_double()
)
{
match_found = true;
match_index_type.push_back('b');
match_index.push_back(j);
}
else if( lit_vectors[i].first_lit_anchor().as_3D_double()
== lit_vectors[j].last_lit_vector().as_3D_double()
)
{
match_found = true;
match_index_type.push_back('c');
match_index.push_back(j);
}
else if( lit_vectors[i].first_lit_anchor().as_3D_double()
== lit_vectors[j].first_lit_anchor().as_3D_double()
)
{
match_found = true;
match_index_type.push_back('d');
match_index.push_back(j);
}
} // end for(j = i; j < (int)lit_vectors.number_of_frames(); j++)
//------------------------------------------------------------
angle = pi;
least_angle = pi;
least_angle_index = 0;
//------------------------------------------------------------
if(match_index.size())
{
for(j = 0; j < (int)match_index.size(); j++)
{
switch(match_index_type[j])
{
case 'a':
angle = three_point_angle(lit_vectors[i].last_lit_anchor(),
lit_vectors[i].last_lit_vector(),
lit_vectors[match_index[j]].first_lit_vertex()
);
break;
case 'b':
angle = three_point_angle(lit_vectors[i].last_lit_anchor(),
lit_vectors[i].last_lit_vector(),
lit_vectors[match_index[j]].last_lit_anchor()
);
break;
case 'c':
angle = three_point_angle(lit_vectors[i].first_lit_vertex(),
lit_vectors[i].first_lit_anchor(),
lit_vectors[match_index[j]].last_lit_anchor()
);
break;
case 'd':
angle = three_point_angle(lit_vectors[i].first_lit_vertex(),
lit_vectors[i].first_lit_anchor(),
lit_vectors[match_index[j]].first_lit_vertex()
);
break;
} // end switch(match_index_type[j])
if(angle <= least_angle)
{
least_angle = angle;
least_angle_index = j;
}
} // end for(j = 0; j < (int)match_index.size(); j++)
//--------------------------------------------------------
switch(match_index_type[least_angle_index])
{
case 'a':
break;
case 'b':
lit_vectors[match_index[least_angle_index]].reverse();
break;
case 'c':
lit_vectors.swap_frames(i, match_index[least_angle_index]);
break;
case 'd':
lit_vectors[i].reverse();
break;
} // end switch(match_index_type[least_angle_index])
//--------------------------------------------------------
lit_vectors[i].is_selected = true;
lit_vectors[match_index[least_angle_index]].is_selected = true;
lit_vectors.collapse_selected_frames();
lit_vectors[i].bond_segments();
//--------------------------------------------------------
break;
} // end if(match_found)
//------------------------------------------------------------
} // end for(i = 0; i < (int)lit_vectors.number_of_frames(); i++)
} while(match_found);
//----------------------------------------------------------------
// lit_vectors.reduce_blank_vectors();
// lit_vectors.reduce_lit_vectors ();
for(i = 0; i < (int)lit_vectors.number_of_frames(); i++)
rs += lit_vectors[i];
*this = rs;
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::sort_by_rotation_xy()
{
if(size() > 1)
{
size_t i;
LaserBoy_3D_double origin,
base_line(32767.0, 0.0, 0.0);
LaserBoy_real_segment rs1(*this),
rs2;
LaserBoy_4D_double_vector _v;
for(i = 0; i < rs1.size(); i++)
{
rs1.at(i).z = 0.0;
_v.push_back(LaserBoy_4D_double(rs1.at(i).as_3D_double(),
three_point_angle_xy(origin, base_line, rs1.at(i))
)
);
}
_v.sort();
for(i = 0; i < _v.size(); i++)
rs2.push_back(LaserBoy_real_vertex( _v.at(i).x,
_v.at(i).y,
_v.at(i).z,
255,
255,
255,
0,
55
)
);
*this = rs2;
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::sort_by_rotation_xz()
{
if(size() > 1)
{
size_t i;
LaserBoy_3D_double origin,
base_line(32767.0, 0.0, 0.0);
LaserBoy_real_segment rs1(*this),
rs2;
LaserBoy_4D_double_vector _v;
for(i = 0; i < rs1.size(); i++)
{
rs1.at(i).y = 0.0;
_v.push_back(LaserBoy_4D_double(rs1.at(i).as_3D_double(),
three_point_angle_xz(origin, base_line, rs1.at(i))
)
);
}
_v.sort();
for(i = 0; i < _v.size(); i++)
rs2.push_back(LaserBoy_real_vertex( _v.at(i).x,
_v.at(i).y,
_v.at(i).z,
255,
255,
255,
0,
55
)
);
*this = rs2;
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::sort_by_rotation_zy()
{
if(size() > 1)
{
size_t i;
LaserBoy_3D_double origin,
base_line(0.0, 32767.0, 0.0);
LaserBoy_real_segment rs1(*this),
rs2;
LaserBoy_4D_double_vector _v;
for(i = 0; i < rs1.size(); i++)
{
rs1.at(i).x = 0.0;
_v.push_back(LaserBoy_4D_double(rs1.at(i).as_3D_double(),
three_point_angle_zy(origin, base_line, rs1.at(i))
)
);
}
_v.sort();
for(i = 0; i < _v.size(); i++)
rs2.push_back(LaserBoy_real_vertex( _v.at(i).x,
_v.at(i).y,
_v.at(i).z,
255,
255,
255,
0,
55
)
);
*this = rs2;
}
return *this;
}
//############################################################################
LaserBoy_real_segment_set LaserBoy_real_segment::explode_segments() const
{
LaserBoy_real_segment_set rss;
//------------------------------------------------------------------------
if(size() > 1)
{
size_t i,
j,
start,
end;
LaserBoy_real_segment rs(palette_index, false);
//----------------------------------------------------------------
for(i = 1; i < size(); i++)
{
if(at(i).is_lit())
{
start = i - 1; // anchor to the first lit vertex
while(at(i).is_lit() && i < (size() - 1))
i++;
//------------------------------------------------------------
end = i - 1;
if( i == (size() - 1)
&& at(i).is_lit()
)
end = i;
//------------------------------------------------------------
rs.clear();
for(j = start; j <= end; j++)
rs.push_back(at(j));
rss.push_back(rs);
}
}
}
//------------------------------------------------------------------------
return rss;
}
//############################################################################
LaserBoy_real_segment LaserBoy_real_segment::copy_segment(size_t segment_index) const
{
LaserBoy_real_segment rs;
rs.palette_index = palette_index;
if(size() > 1)
{
size_t start, end;
if(find_segment_at_index(segment_index, start, end))
{
rs.clear();
rs.reserve(end - start + 1);
for(size_t i = start; i <= end; i++)
rs.push_back(at(i));
}
}
return rs;
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::rectangular_center_of_segment(size_t segment_index) const
{
return (copy_segment(segment_index)).rectangular_center_of();
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::mean_of_coordinates_of_segment(size_t segment_index) const
{
return (copy_segment(segment_index)).mean_of_coordinates();
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::centroid_of_segment_xy(size_t segment_index, double& area, LaserBoy_real_segment& rs) const
{
return (copy_segment(segment_index)).centroid_of_coordinates_xy(area, rs);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::centroid_of_segment_xz(size_t segment_index, double& area, LaserBoy_real_segment& rs) const
{
return (copy_segment(segment_index)).centroid_of_coordinates_xz(area, rs);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::centroid_of_segment_zy(size_t segment_index, double& area, LaserBoy_real_segment& rs) const
{
return (copy_segment(segment_index)).centroid_of_coordinates_zy(area, rs);
}
//############################################################################
LaserBoy_3D_double LaserBoy_real_segment::centroid_of_segment(size_t segment_index) const
{
return (copy_segment(segment_index)).centroid_of_coordinates();
}
//############################################################################
void LaserBoy_real_segment::move_segment(size_t segment_index, LaserBoy_3D_double d)
{
if(size() > 1)
{
size_t i ,
start,
end ;
find_segment_at_index(segment_index, start, end);
//----------------------------------------------------------------
for(i = start; i <= end; i++)
at(i) += d;
}
return;
}
//############################################################################
void LaserBoy_real_segment::center_segment_x(size_t index)
{
if(size() > 1)
{
size_t i,
start,
end;
LaserBoy_3D_double center = rectangular_center_of_segment(index);
find_segment_at_index(index, start, end);
for(i = start; i <= end; i++)
at(i).x = at(i).x - center.x;
}
return;
}
//############################################################################
void LaserBoy_real_segment::center_segment_y(size_t index)
{
if(size() > 1)
{
size_t i,
start,
end;
LaserBoy_3D_double center = rectangular_center_of_segment(index);
find_segment_at_index(index, start, end);
for(i = start; i <= end; i++)
at(i).y = at(i).y - center.y;
}
return;
}
//############################################################################
void LaserBoy_real_segment::center_segment_z(size_t index)
{
if(size() > 1)
{
size_t i,
start,
end;
LaserBoy_3D_double center = rectangular_center_of_segment(index);
find_segment_at_index(index, start, end);
for(i = start; i <= end; i++)
at(i).z = at(i).z - center.z;
}
return;
}
//############################################################################
void LaserBoy_real_segment::center_segment(size_t index)
{
if(size() > 1)
{
size_t i,
start,
end;
LaserBoy_3D_double center = rectangular_center_of_segment(index);
find_segment_at_index(index, start, end);
for(i = start; i <= end; i++)
at(i) = at(i) - center;
}
return;
}
//############################################################################
void LaserBoy_real_segment::rotate_segment(size_t segment_index, LaserBoy_3D_double a)
{
if(size() > 1)
{
size_t i,
start,
end;
LaserBoy_3D_double center = centroid_of_segment(segment_index);
find_segment_at_index(segment_index, start, end);
for(i = start; i <= end; i++)
at(i) = rotate_vertex_on_coordinates(at(i), center, a);
}
return;
}
//############################################################################
void LaserBoy_real_segment::rotate_segment_around_origin(size_t segment_index, LaserBoy_3D_double a)
{
if(size() > 1)
{
size_t i ,
start,
end ;
find_segment_at_index(segment_index, start, end);
//----------------------------------------------------------------
for(i = start; i <= end; i++)
at(i) = rotate_vertex(at(i), a);
}
return;
}
//############################################################################
void LaserBoy_real_segment::scale_segment(size_t segment_index, LaserBoy_3D_double m)
{
if(size() > 1)
{
size_t i ,
start ,
end ;
LaserBoy_3D_double center;
//----------------------------------------------------------------
find_segment_at_index(segment_index, start, end);
center = centroid_of_segment(segment_index);
//----------------------------------------------------------------
for(i = start; i <= end; i++)
at(i) = scale_vertex_on_coordinates(at(i), center, m);
//----------------------------------------------------------------
}
return;
}
//############################################################################
void LaserBoy_real_segment::scale_segment_around_origin(size_t segment_index, LaserBoy_3D_double m)
{
if(size() > 1)
{
size_t i ,
start,
end ;
//----------------------------------------------------------------
find_segment_at_index(segment_index, start, end);
//----------------------------------------------------------------
for(i = start; i <= end; i++)
at(i) *= m;
//----------------------------------------------------------------
}
return;
}
//############################################################################
bool LaserBoy_real_segment::save_as_bmp(const string& file,
u_int x_res,
u_int y_res,
u_int rendered_line_width,
bool bmp_render_vectors,
bool bmp_render_vertices,
double scale
) const
{
int bmp_center_x = x_res / 2,
bmp_center_y = y_res / 2;
char file_name[80];
LaserBoy_3D_double _0,
_1;
struct LaserBoy_bmp bmp_out = {0};
LaserBoy_real_segment copy(*this);
if(size() > 1)
{
p_space->p_GUI->display_state("rendering bmp file " + file);
//--------------------------------------------------------------------
if(copy.number_of_unique_colors() == 1)
{
bmp_init(&bmp_out, x_res, y_res, 1);
bmp_clear(&bmp_out, 1);
copy.promote_to_true_color();
copy.best_reduce_to_palette();
if(p_space->palette_picker(copy.palette_index).to_bmp_palette(&bmp_out))
{
bmp_set_palette_index(&bmp_out, 0, 255, 255, 255);
bmp_set_palette_index(&bmp_out, 1, 0, 0, 0);
}
}
else if(copy.number_of_unique_colors() <= 15)
{
bmp_init(&bmp_out, x_res, y_res, 4);
bmp_clear(&bmp_out, 15);
copy.promote_to_true_color();
copy.best_reduce_to_palette();
if(p_space->palette_picker(copy.palette_index).to_bmp_palette(&bmp_out))
return false;
}
else if(copy.number_of_unique_colors() <= 255)
{
if(copy.palette_index == LASERBOY_TRUE_COLOR)
copy.best_reduce_to_palette();
bmp_init(&bmp_out, x_res, y_res, 8);
bmp_clear(&bmp_out, 255);
p_space->palette_picker(copy.palette_index).to_bmp_palette(&bmp_out);
}
else
{
bmp_init(&bmp_out, x_res, y_res, 24);
bmp_clear(&bmp_out, 0x00000000);
}
if(scale == 0)
{
copy.to_unit(false);
LaserBoy_3D_double WxHxD,
center;
WxHxD = copy.dimensions(center, false);
if(WxHxD.x != 0 && WxHxD.y != 0)
scale = ( bmp_out.xres / WxHxD.x
<= bmp_out.yres / WxHxD.y
)
? (bmp_out.xres / WxHxD.x)
: (bmp_out.yres / WxHxD.y);
copy.move(-center);
}
//----------------------------------------------------------------
if(scale != 0)
{
for(size_t i = 1; i < copy.size(); i++)
{
if(copy.at(i).is_color(p_space->black_level))
{
_0 = copy.at(i - 1);
_1 = copy.at(i );
//------------------------------------------------------------
if(copy.palette_index == LASERBOY_TRUE_COLOR)
{
if(bmp_render_vectors)
bmp_put_thick_line_fast( &bmp_out
, (int)(_0.x * scale) + bmp_center_x
, ((int)(_0.y * scale) + bmp_center_y)
, (int)(_1.x * scale) + bmp_center_x
, ((int)(_1.y * scale) + bmp_center_y)
, bmp_out.make_rgb(copy.at(i).r, copy.at(i).g, copy.at(i).b)
, p_space->rendered_line_width
);
if(bmp_render_vertices)
bmp_put_vertex(&bmp_out,
(int)(_1.x * scale) + bmp_center_x,
((int)(_1.y * scale) + bmp_center_y),
bmp_out.make_rgb(copy.at(i).r, copy.at(i).g, copy.at(i).b),
rendered_line_width
);
}
else
{
if(bmp_render_vectors)
bmp_put_thick_line_fast( &bmp_out
, (int)(_0.x * scale) + bmp_center_x
, ((int)(_0.y * scale) + bmp_center_y)
, (int)(_1.x * scale) + bmp_center_x
, ((int)(_1.y * scale) + bmp_center_y)
, copy.at(i).c
, p_space->rendered_line_width
);
if(bmp_render_vertices)
bmp_put_vertex(&bmp_out,
(int)(_1.x * scale) + bmp_center_x,
((int)(_1.y * scale) + bmp_center_y),
copy.at(i).c,
rendered_line_width
);
}
} // end if(copy.at(i).is_color(p_space->black_level))
} // for(size_t i = 1; i < copy.size(); i++)
} // end if(scale != 0)
} // end if(size() > 1)
else
{
bmp_init(&bmp_out, p_space->output_bmp_size, p_space->output_bmp_size, 1);
bmp_set_palette_index(&bmp_out, 0, 255, 255, 255);
bmp_set_palette_index(&bmp_out, 1, 0, 0, 0);
bmp_clear(&bmp_out, 1);
}
sprintf(file_name, "%s", file.c_str());
p_space->p_GUI->display_state("writing bmp file " + string(file_name));
bmp_save_as(&bmp_out, file_name);
bmp_free(&bmp_out);
return true;
}
//############################################################################
LaserBoy_Error_Code LaserBoy_real_segment::from_ifstream_txt(std::ifstream& in,
const u_int& group_type,
int& line_number
)
{
LaserBoy_real_vertex real_vertex;
//------------------------------------------------------------------------
if( group_type == LASERBOY_3D_FRAME_PALETTE
|| group_type == LASERBOY_2D_FRAME_PALETTE
)
palette_index = p_space->palette_index;
else
palette_index = LASERBOY_TRUE_COLOR;
//------------------------------------------------------------------------
clear();
push_back(LaserBoy_real_vertex());
push_back(LaserBoy_real_vertex());
//------------------------------------------------------------------------
if(in.good())
{
real_segment_error = LASERBOY_OK;
while(real_vertex.from_ifstream_txt(in, group_type, line_number))
push_back(real_vertex);
sync_rgb_and_palette();
}
else
real_segment_error = LASERBOY_EOF;
//------------------------------------------------------------------------
return real_segment_error;
}
//############################################################################
void LaserBoy_real_segment::to_ofstream_txt_color_table(std::ofstream& out)
{
out << "# ---------------------------------------------------------------"
<< ENDL
<< "table ";
if(p_space->save_txt_color_hex)
out << "hex";
else
out << "rgb";
out << ENDL;
//------------------------------------------------------------------------
for(size_t i = 0; i < size(); i++)
if(at(i).is_lit())
((LaserBoy_color)at(i)).to_ofstream_txt(out, p_space->save_txt_color_hex);
else
out << " -1"
<< ENDL;
//------------------------------------------------------------------------
out << ENDL;
return;
}
//############################################################################
void LaserBoy_real_segment::to_ofstream_txt(std::ofstream& out, int frame_index)
{
int output_format = ( (is_2D())
? ( (p_space->save_txt_with_color)
? (LASERBOY_2D_FRAME_RGB)
: ( (palette_index == LASERBOY_TRUE_COLOR)
? (LASERBOY_2D_FRAME_TABLE)
: (LASERBOY_2D_FRAME_PALETTE)
)
) // 3D
: ( (p_space->save_txt_with_color)
? (LASERBOY_3D_FRAME_RGB)
: ( (palette_index == LASERBOY_TRUE_COLOR)
? (LASERBOY_3D_FRAME_TABLE)
: (LASERBOY_3D_FRAME_PALETTE)
)
)
);
//------------------------------------------------------------------------
if(frame_index >= 0)
out << "# " << setw(6) << frame_index << " ---------------------------------------------------------" << ENDL;
out << "frame ";
//------------------------------------------------------------------------
switch(output_format)
{
case LASERBOY_2D_FRAME_RGB:
case LASERBOY_2D_FRAME_TABLE:
case LASERBOY_2D_FRAME_PALETTE:
out << "xy ";
break;
case LASERBOY_3D_FRAME_RGB:
case LASERBOY_3D_FRAME_TABLE:
case LASERBOY_3D_FRAME_PALETTE:
out << "xyz ";
break;
}
//------------------------------------------------------------------------
switch(output_format)
{
case LASERBOY_2D_FRAME_RGB:
case LASERBOY_3D_FRAME_RGB:
if(p_space->save_txt_color_hex)
out << "hex";
else
out << "rgb";
break;
case LASERBOY_2D_FRAME_TABLE:
case LASERBOY_3D_FRAME_TABLE:
out << "table";
break;
case LASERBOY_2D_FRAME_PALETTE:
case LASERBOY_3D_FRAME_PALETTE:
out << "palette";
break;
}
//------------------------------------------------------------------------
out << " real" << ENDL;
switch(output_format)
{
case LASERBOY_3D_FRAME_PALETTE:
for(size_t i = 0; i < size(); i++)
out << " "
<< showpos
<< setw(20) << left << at(i).x
<< setw(20) << left << at(i).y
<< setw(20) << left << at(i).z
<< noshowpos
<< setw(7) << ((at(i).is_lit()) ? ((int)at(i).c) : (-1))
<< ENDL;
break;
//--------------------------------------------------------------------
case LASERBOY_2D_FRAME_PALETTE:
for(size_t i = 0; i < size(); i++)
out << " "
<< showpos
<< setw(20) << left << at(i).x
<< setw(20) << left << at(i).y
<< noshowpos
<< setw(7) << ((at(i).is_lit()) ? ((int)at(i).c) : (-1))
<< ENDL;
break;
//--------------------------------------------------------------------
case LASERBOY_3D_FRAME_TABLE: // nothing but x y z
for(size_t i = 0; i < size(); i++)
out << " "
<< showpos
<< setw(20) << left << at(i).x
<< setw(20) << left << at(i).y
<< setw(20) << left << at(i).z
<< noshowpos
<< ENDL;
break;
//--------------------------------------------------------------------
case LASERBOY_2D_FRAME_TABLE: // nothing but x y
for(size_t i = 0; i < size(); i++)
out << " "
<< showpos
<< setw(20) << left << at(i).x
<< setw(20) << left << at(i).y
<< noshowpos
<< ENDL;
break;
//--------------------------------------------------------------------
case LASERBOY_3D_FRAME_RGB:
for(size_t i = 0; i < size(); i++)
{
out << " "
<< showpos
<< setw(20) << left << at(i).x
<< setw(20) << left << at(i).y
<< setw(20) << left << at(i).z
<< noshowpos;
if(p_space->save_txt_color_hex)
{
if(at(i).is_lit())
out << " 0x"
<< hex
<< setw(6)
<< right
<< setfill('0')
<< at(i).as_uint()
<< dec
<< left
<< setfill(' ');
else
out << " -1";
}
else
{
if(at(i).is_lit())
out << setw(7) << (int)at(i).r
<< setw(7) << (int)at(i).g
<< setw(7) << (int)at(i).b;
else
out << " -1";
}
out << ENDL;
}
break;
//--------------------------------------------------------------------
case LASERBOY_2D_FRAME_RGB:
for(size_t i = 0; i < size(); i++)
{
out << " "
<< showpos
<< setw(20) << left << at(i).x
<< setw(20) << left << at(i).y
<< noshowpos;
if(p_space->save_txt_color_hex)
{
if(at(i).is_lit())
out << " 0x"
<< hex
<< setw(6)
<< right
<< setfill('0')
<< at(i).as_uint()
<< dec
<< left
<< setfill(' ');
else
out << " -1";
}
else
{
if(at(i).is_lit())
out << setw(7) << (int)at(i).r
<< setw(7) << (int)at(i).g
<< setw(7) << (int)at(i).b;
else
out << " -1";
}
out << ENDL;
}
break;
//--------------------------------------------------------------------
}
out << ENDL;
//------------------------------------------------------------------------
return;
}
//############################################################################
LaserBoy_Error_Code LaserBoy_real_segment::from_ifstream_dxf(std::ifstream& in)
{
u_char dxf_color_index ,
prev_dxf_color_index;
u_int arc_vertices = 0 ,
group_70_flag = 0 ,
group_71_flag = 0 ,
group_72_flag = 0 ,
group_73_flag = 0 ;
int group_code ,
first_segment_vertex_index;
double double_value,
radius ,
arc_start ,
arc_end ,
arc_angle ,
arc_step ;
string entity_string,
font ,
text ;
LaserBoy_ild_header_count counter;
LaserBoy_3D_double double_3D_1,
double_3D_2,
double_3D_3,
double_3D_4;
LaserBoy_color color,
prev_color;
LaserBoy_real_segment real_vertices;
vector vertex_x,
vertex_y,
vertex_z;
bool closed_polyline;
//------------------------------------------------------------------------
palette_index = LASERBOY_DXF;
push_back(LaserBoy_real_vertex()); // every LaserBoy_real_segment::from_ifstream_dxf
push_back(LaserBoy_real_vertex()); // has an original vector this.size() not less than 2
//------------------------------------------------------------------------
while(in.good() && entity_string != "ENTITIES") // ignore everthing up to ENTITIES
in >> entity_string;
//------------------------------------------------------------------------
if(in.good())
{
while(in.good())
{
dxf_color_index = p_space->palette_picker(LASERBOY_DXF).white;
prev_dxf_color_index = p_space->palette_picker(LASERBOY_DXF).white;
color = (u_int)0X00ffffff;
prev_color = (u_int)0X00ffffff;
first_segment_vertex_index = -1,
closed_polyline = false;
group_70_flag = 0;
radius = 0;
arc_vertices = 0;
arc_start = 0;
arc_end = 360;
group_code = -1;
//----------------------------------------------------------------
vertex_x.clear();
vertex_y.clear();
vertex_z.clear();
//----------------------------------------------------------------
if(entity_string == "POINT")
{
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
switch(group_code)
{
case 10: // x1
double_3D_1.x = double_value;
break;
case 20: // y1
double_3D_1.y = double_value;
break;
case 30: // z1
double_3D_1.z = double_value;
break;
case 62: // palette_index
color = p_space->palette_picker(LASERBOY_DXF)[(u_char)double_value];
if(color.is_black())
color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
break;
case 420: // true color
color = (u_int)double_value;
if(color.is_black())
color = (u_int)0X00ffffff;
palette_index = LASERBOY_TRUE_COLOR;
break;
}
}
push_back(LaserBoy_real_vertex(double_3D_1, color).blank());
push_back(LaserBoy_real_vertex(double_3D_1, color).unblank());
}
else if(entity_string == "LINE")
{
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
switch(group_code)
{
case 10: // x1
double_3D_1.x = double_value;
break;
case 20: // y1
double_3D_1.y = double_value;
break;
case 30: // z1
double_3D_1.z = double_value;
break;
case 11: // x2
double_3D_2.x = double_value;
break;
case 21: // y2
double_3D_2.y = double_value;
break;
case 31: // z2
double_3D_2.z = double_value;
break;
case 62: // dxf_color_index
color = p_space->palette_picker(LASERBOY_DXF)[(u_char)double_value];
if(color.is_black())
color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
break;
case 420: // true color
color = (u_int)double_value;
if(color.is_black())
color = (u_int)0X00ffffff;
palette_index = LASERBOY_TRUE_COLOR;
break;
}
}
push_back(LaserBoy_real_vertex(double_3D_1, color).blank());
push_back(LaserBoy_real_vertex(double_3D_2, color).unblank());
}
//----------------------------------------------------------------
else if( entity_string == "CIRCLE"
|| entity_string == "ARC"
)
{
u_int a;
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
switch(group_code)
{
case 10: // x1
double_3D_1.x = double_value;
break;
case 20: // y1
double_3D_1.y = double_value;
break;
case 30: // z1
double_3D_1.z = double_value;
break;
case 40: // radius
radius = double_value;
break;
case 50: // start angle
arc_start = double_value;
break;
case 51: // end angle
arc_end = double_value;
break;
case 62: // dxf_color_index
color = p_space->palette_picker(LASERBOY_DXF)[(u_char)double_value];
if(color.is_black())
color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
break;
case 420: // true color
color = (u_int)double_value;
if(color.is_black())
color = (u_int)0X00ffffff;
palette_index = LASERBOY_TRUE_COLOR;
break;
}
}
if(arc_start >= arc_end)
arc_end += 360.0;
arc_angle = arc_end - arc_start;
arc_vertices = (int)ceil(arc_angle / p_space->rendered_arc_angle);
arc_step = arc_angle / arc_vertices;
arc_start *= one_degree;
arc_end *= one_degree;
arc_step *= one_degree;
double_3D_2.x = radius * cos(arc_start);
double_3D_2.y = radius * sin(arc_start);
double_3D_2.z = double_3D_1.z;
push_back(LaserBoy_real_vertex(double_3D_1 + double_3D_2, color).blank());
for(a = 1; a <= arc_vertices; a++)
{
double_3D_2.x = radius * cos(a * arc_step + arc_start);
double_3D_2.y = radius * sin(a * arc_step + arc_start);
double_3D_2.z = double_3D_1.z;
push_back(LaserBoy_real_vertex(double_3D_1 + double_3D_2, color).unblank());
}
}
//----------------------------------------------------------------
else if(entity_string == "ELLIPSE")
{
u_int a,
vertex_index;
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
switch(group_code)
{
case 10: // x1
double_3D_1.x = double_value;
break;
case 20: // y1
double_3D_1.y = double_value;
break;
case 30: // z1
double_3D_1.z = double_value;
break;
case 11: // x2
double_3D_2.x = double_value;
break;
case 21: // y2
double_3D_2.y = double_value;
break;
case 31: // z2
double_3D_2.z = double_value;
break;
case 40: // ratio between major and minor axis
radius = double_value;
break;
case 41: // start angle
arc_start = double_value;
break;
case 42: // end angle
arc_end = double_value;
break;
case 62: // dxf_color_index
color = p_space->palette_picker(LASERBOY_DXF)[(u_char)double_value];
if(color.is_black())
color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
break;
case 420: // true color
color = (u_int)double_value;
if(color.is_black())
color = (u_int)0X00ffffff;
palette_index = LASERBOY_TRUE_COLOR;
break;
}
}
if(arc_start >= arc_end) arc_end += two_pi;
arc_angle = arc_end - arc_start;
arc_vertices = (int)ceil(arc_angle / (p_space->rendered_arc_angle * one_degree));
arc_step = arc_angle / arc_vertices;
double major_axis = double_3D_2.magnitude(),
minor_axis = major_axis * radius;
double_3D_3 = 0.0;
double_3D_3.z = -double_3D_2.direction().z;
real_vertices.clear();
double_3D_4.x = -major_axis * cos(arc_start);
double_3D_4.y = -minor_axis * sin(arc_start);
double_3D_4.z = double_3D_1.z;
real_vertices.push_back(LaserBoy_real_vertex(double_3D_4, color).blank());
for(a = 1; a <= arc_vertices; a++)
{
double_3D_4.x = -major_axis * cos(a * arc_step + arc_start);
double_3D_4.y = -minor_axis * sin(a * arc_step + arc_start);
double_3D_4.z = double_3D_1.z;
real_vertices.push_back(LaserBoy_real_vertex(double_3D_4, color).unblank());
}
if(double_3D_3 != 0.0)
for(vertex_index = 0; vertex_index < real_vertices.size(); vertex_index++)
real_vertices[vertex_index] = rotate_vertex(real_vertices[vertex_index], double_3D_3);
for(vertex_index = 0; vertex_index < real_vertices.size(); vertex_index++)
push_back(real_vertices[vertex_index] + double_3D_1);
}
//----------------------------------------------------------------
else if(entity_string == "POLYLINE")
{
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
switch(group_code)
{
case 62: // dxf_color_index
dxf_color_index = (u_char)double_value;
prev_dxf_color_index = dxf_color_index;
prev_color = p_space->palette_picker(LASERBOY_DXF)[dxf_color_index];
if(prev_color.is_black())
prev_color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
color = p_space->palette_picker(LASERBOY_DXF)[dxf_color_index];
if(color.is_black())
color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
break;
case 420: // true color
color = (u_int)double_value;
if(color.is_black())
color = (u_int)0X00ffffff;
prev_color = color;
palette_index = LASERBOY_TRUE_COLOR;
break;
case 70:
if(((int)double_value) & 0x01)
closed_polyline = true;
break;
}
}
while(entity_string == "VERTEX")
{
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
switch(group_code)
{
case 10: // x1
double_3D_1.x = double_value;
break;
case 20: // y1
double_3D_1.y = double_value;
break;
case 30: // z1
double_3D_1.z = double_value;
break;
case 62: // dxf_color_index
prev_dxf_color_index = dxf_color_index;
dxf_color_index = (u_char)double_value;
prev_color = p_space->palette_picker(LASERBOY_DXF)[prev_dxf_color_index];
if(prev_color.is_black())
prev_color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
color = p_space->palette_picker(LASERBOY_DXF)[(u_char)double_value];
if(color.is_black())
color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
break;
case 420: // true color
prev_color = color;
color = (u_int)double_value;
if(color.is_black())
color = (u_int)0X00ffffff;
palette_index = LASERBOY_TRUE_COLOR;
break;
}
}
if(first_segment_vertex_index == -1)
{
push_back(LaserBoy_real_vertex(double_3D_1, color).blank());
first_segment_vertex_index = (int)size() - 1;
}
else
push_back(LaserBoy_real_vertex(double_3D_1, prev_color).unblank());
} // end while(entity_string == "VERTEX")
if(closed_polyline)
push_back(LaserBoy_real_vertex((LaserBoy_3D_double)(at(first_segment_vertex_index)), back().as_color()).unblank());
}
//----------------------------------------------------------------
else if(entity_string == "LWPOLYLINE")
{
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
switch(group_code)
{
case 10: // x
vertex_x.push_back(double_value);
break;
case 20: // y
vertex_y.push_back(double_value);
break;
case 62: // dxf_color_index
color = p_space->palette_picker(LASERBOY_DXF)[(u_char)double_value];
if(color.is_black())
color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
break;
case 420: // true color
color = (u_int)double_value;
if(color.is_black())
color = (u_int)0X00ffffff;
palette_index = LASERBOY_TRUE_COLOR;
break;
case 70: // is closed polyline
group_70_flag = (int)double_value;
break;
case 90: // number of verticies
arc_vertices = (int)double_value;
break;
}
}
if( (arc_vertices > 0)
&& (arc_vertices == vertex_x.size())
&& (arc_vertices == vertex_y.size())
)
{
double_3D_1.x = vertex_x.front();
double_3D_1.y = vertex_y.front();
double_3D_1.z = 0;
push_back(LaserBoy_real_vertex(double_3D_1, color).blank());
for(u_int a = 0; a < arc_vertices; a++)
{
double_3D_1.x = vertex_x[a];
double_3D_1.y = vertex_y[a];
push_back(LaserBoy_real_vertex(double_3D_1, color).unblank());
}
if(group_70_flag & 0x01) // closed polyline
{
double_3D_1.x = vertex_x.front();
double_3D_1.y = vertex_y.front();
push_back(LaserBoy_real_vertex(double_3D_1, color).unblank());
}
}
}
//----------------------------------------------------------------
else if(entity_string == "3DFACE")
{
u_int vertex_count = 0;
vertex_x.resize(10);
vertex_y.resize(10);
vertex_z.resize(10);
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
if (group_code < 20 && group_code > 9)
{
vertex_x[group_code - 10] = double_value;
vertex_count++;
}
else if(group_code < 30 && group_code > 19)
vertex_y[group_code - 20] = double_value;
else if(group_code < 40 && group_code > 29)
vertex_z[group_code - 30] = double_value;
}
double_3D_1.x = vertex_x.front();
double_3D_1.y = vertex_y.front();
double_3D_1.z = vertex_z.front();
push_back(LaserBoy_real_vertex(double_3D_1, color).blank());
for(u_int a = 0; a < vertex_count; a++)
{
double_3D_1.x = vertex_x[a];
double_3D_1.y = vertex_y[a];
double_3D_1.z = vertex_z[a];
push_back(LaserBoy_real_vertex(double_3D_1, color).unblank());
}
double_3D_1.x = vertex_x.front();
double_3D_1.y = vertex_y.front();
double_3D_1.z = vertex_z.front();
push_back(LaserBoy_real_vertex(double_3D_1, color).unblank());
}
//----------------------------------------------------------------
else if(entity_string == "TEXT")
{
int text_index,
vertex_index;
long int bytes_skipped;
LaserBoy_frame_set font_frames;
double_3D_1 = 0.0;
double_3D_3 = 0.0;
while(get_dxf_pair(in, group_code, entity_string))
{
sscanf(entity_string.c_str(), "%lf", &double_value);
switch(group_code)
{
case 1: // the text
text = entity_string;
break;
case 7: // the font
font = entity_string;
break;
case 10: // x1
double_3D_1.x = double_value;
break;
case 20: // y1
double_3D_1.y = double_value;
break;
case 30: // z1
double_3D_1.z = double_value;
break;
case 40: // text height
radius = double_value;
break;
case 50: // flat rotation angle
double_3D_3.z = double_value * one_degree;
break;
case 51: // oblique rotation angle
double_3D_3.y = double_value * one_degree;
break;
case 62: // dxf_color_index
color = p_space->palette_picker(LASERBOY_DXF)[(u_char)double_value];
if(color.is_black())
color = p_space->palette_picker(LASERBOY_DXF)[p_space->palette_picker(LASERBOY_DXF).white];
break;
case 420: // true color
color = (u_int)double_value;
if(color.is_black())
color = (u_int)0X00ffffff;
palette_index = LASERBOY_TRUE_COLOR;
break;
case 71: // flipped or mirrored
group_71_flag = (int)double_value;
break;
case 72: // horizontal justification
group_72_flag = (int)double_value;
break;
case 73: // vertical justification
group_73_flag = (int)double_value;
break;
}
}
//------------------------------------------------------------
if(font == "ARIAL")
font_frames.from_ild_file(LASERBOY_ILD_SHARE + string("fonts/") + "arial.ild", bytes_skipped, counter);
else if(font == "COMIC_SANS_MS")
font_frames.from_ild_file(LASERBOY_ILD_SHARE + string("fonts/") + "comic_sans.ild", bytes_skipped, counter);
else if(font == "COURIER_NEW")
font_frames.from_ild_file(LASERBOY_ILD_SHARE + string("fonts/") + "courier_new.ild", bytes_skipped, counter);
else if(font == "LUCIDA_CONSOLE")
font_frames.from_ild_file(LASERBOY_ILD_SHARE + string("fonts/") + "lucida.ild", bytes_skipped, counter);
else if(font == "IMPACT")
font_frames.from_ild_file(LASERBOY_ILD_SHARE + string("fonts/") + "impact.ild", bytes_skipped, counter);
else if(font == "TIMES_NEW_ROMAN")
font_frames.from_ild_file(LASERBOY_ILD_SHARE + string("fonts/") + "times_new_roman.ild", bytes_skipped, counter);
else
font_frames.from_ild_file(LASERBOY_ILD_SHARE + string("fonts/") + "narrow_vector.ild", bytes_skipped, counter);
if( font_frames.frame_set_error != LASERBOY_OK
|| font_frames.number_of_frames() < (('~' - '!') + 1)
)
real_segment_error = LASERBOY_BAD_FONT_FILE;
else
{
real_vertices.clear();
for(text_index = 0; text_index < (int)text.size(); text_index++)
{
if(text[text_index] >= '!' && text[text_index] <= '~')
{
for(vertex_index = 0; vertex_index < (int)font_frames[text[text_index] - '!'].size(); vertex_index++)
{
double_3D_2 = font_frames[text[text_index] - '!'].at(vertex_index);
//------------------------------------------------
double_3D_2.x = ( ( double_3D_2.x
/ ( p_space->rendered_mono_font_space
* LASERBOY_MAX_SHORT
)
+ (double)(text_index)
)
) * radius;
//------------------------------------------------
double_3D_2.y = ( ( double_3D_2.y
/ ( p_space->rendered_mono_font_space
* LASERBOY_MAX_SHORT
)
)
) * radius;
//------------------------------------------------
real_vertices.push_back( (font_frames[text[text_index] - '!'].at(vertex_index).is_blank())
? (LaserBoy_real_vertex(double_3D_2, color).blank())
: ( (font_frames[text[text_index] - '!'].at(vertex_index).is_black(p_space->black_level))
? (LaserBoy_real_vertex(double_3D_2, LaserBoy_color(0,0,0)).unblank())
: (LaserBoy_real_vertex(double_3D_2, color).unblank())
)
);
}
}
}
if(group_71_flag & 2) // mirrored
real_vertices.flip(0);
if(group_71_flag & 4) // flipped
real_vertices.flip(1);
if(double_3D_3 != 0.0)
for(vertex_index = 0; vertex_index < (int)real_vertices.size(); vertex_index++)
real_vertices[vertex_index] = rotate_vertex(real_vertices[vertex_index], double_3D_3);
for(vertex_index = 0; vertex_index < (int)real_vertices.size(); vertex_index++)
push_back(real_vertices[vertex_index] + double_3D_1);
}
} // end else if(entity_string == "TEXT")
//----------------------------------------------------------------
else if(entity_string == "ENDSEC")
break;
//----------------------------------------------------------------
else
get_dxf_pair(in, group_code, entity_string);
} // end while(in.good())
// sync_rgb_and_palette();
} // end if(in.good())
//------------------------------------------------------------------------
else
real_segment_error = LASERBOY_EOF;
//------------------------------------------------------------------------
return real_segment_error;
}
//############################################################################
bool LaserBoy_real_segment::save_as_dxf(const string& file, bool save_true_color_dxf) const
{
std::ofstream out(file.c_str(), ios::out);
if(out.is_open())
{
size_t segment_vector_index,
vertex_index;
LaserBoy_real_segment_set rss;
//----------------------------------------------------------------
rss = explode_segments();
//----------------------------------------------------------------
out << " 0\n"
"SECTION\n"
" 2\n"
"ENTITIES\n";
//----------------------------------------------------------------
for(segment_vector_index = 0; segment_vector_index < rss.size(); segment_vector_index++)
{
if(rss[segment_vector_index].number_of_color_vectors() == 1)
{
if( (LaserBoy_3D_double)rss[segment_vector_index].first_lit_anchor()
== (LaserBoy_3D_double)rss[segment_vector_index].first_lit_vertex()
)
{
out << " 0\n"
"POINT\n";
if(save_true_color_dxf)
out << " 420\n"
<< rss[segment_vector_index].first_lit_vertex().color_of(p_space->black_level);
else
out << " 62\n"
<< p_space->
palette_picker(LASERBOY_DXF)
.best_match(rss[segment_vector_index].first_lit_vertex());
out << "\n 10\n"
<< rss[segment_vector_index].first_lit_anchor().x
<< "\n 20\n"
<< rss[segment_vector_index].first_lit_anchor().y
<< "\n 30\n"
<< rss[segment_vector_index].first_lit_anchor().z
<< "\n";
}
else
{
out << " 0\n"
"LINE\n";
if(save_true_color_dxf)
out << " 420\n"
<< rss[segment_vector_index].first_lit_vertex().color_of(p_space->black_level);
else
out << " 62\n"
<< p_space->
palette_picker(LASERBOY_DXF)
.best_match(rss[segment_vector_index].first_lit_vertex());
out << "\n 10\n"
<< rss[segment_vector_index].first_lit_anchor().x
<< "\n 20\n"
<< rss[segment_vector_index].first_lit_anchor().y
<< "\n 30\n"
<< rss[segment_vector_index].first_lit_anchor().z
<< "\n 11\n"
<< rss[segment_vector_index].first_lit_vertex().x
<< "\n 21\n"
<< rss[segment_vector_index].first_lit_vertex().y
<< "\n 31\n"
<< rss[segment_vector_index].first_lit_vertex().z
<< "\n";
}
}
//----------------------------------------------------------------
else
{
out << " 0\n"
"POLYLINE\n"
" 70\n"
<< rss[segment_vector_index].is_closed_polygon()
<< "\n 10\n"
"0.00\n"
" 20\n"
"0.00\n"
" 30\n"
"0.00\n"
//---------
" 0\n"
"VERTEX\n";
if(save_true_color_dxf)
out << " 420\n"
<< rss[segment_vector_index].at(1).color_of(p_space->black_level);
else
out << " 62\n"
<< p_space->
palette_picker(LASERBOY_DXF)
.best_match(rss[segment_vector_index].at(1));
out << "\n 10\n"
<< rss[segment_vector_index].first_lit_anchor().x
<< "\n 20\n"
<< rss[segment_vector_index].first_lit_anchor().y
<< "\n 30\n"
<< rss[segment_vector_index].first_lit_anchor().z
<< "\n";
for(vertex_index = 1; vertex_index < rss[segment_vector_index].size() - 1; vertex_index++)
{
out << " 0\n"
<< "VERTEX\n";
if(save_true_color_dxf)
out << " 420\n"
<< rss[segment_vector_index].at(vertex_index + 1).color_of(p_space->black_level);
else
out << " 62\n"
<< p_space->
palette_picker(LASERBOY_DXF)
.best_match(rss[segment_vector_index].at(vertex_index + 1));
out << "\n 10\n"
<< rss[segment_vector_index].at(vertex_index).x
<< "\n 20\n"
<< rss[segment_vector_index].at(vertex_index).y
<< "\n 30\n"
<< rss[segment_vector_index].at(vertex_index).z
<< "\n";
}
out << " 0\n"
"VERTEX\n";
if(save_true_color_dxf)
out << " 420\n";
else
out << " 62\n";
out << "0\n"
" 10\n"
<< rss[segment_vector_index].at(vertex_index).x
<< "\n 20\n"
<< rss[segment_vector_index].at(vertex_index).y
<< "\n 30\n"
<< rss[segment_vector_index].at(vertex_index).z
<< "\n";
}
}
//----------------------------------------------------------------
out << " 0\n"
"ENDSEC\n"
" 0\n"
"EOF\n";
//----------------------------------------------------------------
out.close();
return true;
}
return false;
}
//############################################################################
void LaserBoy_real_segment::normalize(bool ignore_origin) // if(p_space->maintain_real_origin)
{
if(size() > 2)
{
int _x,
_y,
_z;
size_t i,
start = 0;
double real_size = 0.0,
real_scale = 1.0;
LaserBoy_3D_double real_min = DBL_MAX,
real_max = -DBL_MAX,
real_offset = 0.0;
if(ignore_origin)
start = 2;
for(i = start; i < size(); i++) // ignore the origin vector
{
if(at(i).x > real_max.x) real_max.x = at(i).x;
if(at(i).x < real_min.x) real_min.x = at(i).x;
if(at(i).y > real_max.y) real_max.y = at(i).y;
if(at(i).y < real_min.y) real_min.y = at(i).y;
if(at(i).z > real_max.z) real_max.z = at(i).z;
if(at(i).z < real_min.z) real_min.z = at(i).z;
}
if(p_space->maintain_real_origin)
{
if(fabs(real_max.x) > real_size)
real_size = fabs(real_max.x);
if(fabs(real_min.x) > real_size)
real_size = fabs(real_min.x);
if(fabs(real_max.y) > real_size)
real_size = fabs(real_max.y);
if(fabs(real_min.y) > real_size)
real_size = fabs(real_min.y);
if(fabs(real_max.z) > real_size)
real_size = fabs(real_max.z);
if(fabs(real_min.z) > real_size)
real_size = fabs(real_min.z);
real_size *= 2;
}
else // find the new center of the universe
{
real_offset.x = (real_max.x - ((real_max.x - real_min.x) / 2));
real_offset.y = (real_max.y - ((real_max.y - real_min.y) / 2));
real_offset.z = (real_max.z - ((real_max.z - real_min.z) / 2));
if(fabs(real_max.x - real_min.x) > real_size)
real_size = fabs(real_max.x - real_min.x);
if(fabs(real_max.y - real_min.y) > real_size)
real_size = fabs(real_max.y - real_min.y);
if(fabs(real_max.z - real_min.z) > real_size)
real_size = fabs(real_max.z - real_min.z);
}
real_scale = 65535.0 / real_size;
//----------------------------------------------------------------
for(i = start; i < size(); i++) // ignore the origin vector
{
_x = (int)round((at(i).x - real_offset.x) * real_scale);
_y = (int)round((at(i).y - real_offset.y) * real_scale);
_z = (int)round((at(i).z - real_offset.z) * real_scale);
if(_x > 32767) _x = 32767;
if(_x < -32767) _x = -32767;
if(_y > 32767) _y = 32767;
if(_y < -32767) _y = -32767;
if(_z > 32767) _z = 32767;
if(_z < -32767) _z = -32767;
at(i).x = (double)(_x);
at(i).y = (double)(_y);
at(i).z = (double)(_z);
}
}
//--------------------------------------------------------------------
return;
}
//############################################################################
void LaserBoy_real_segment::normalize_vectors(bool ignore_origin)
{
if(size() > 2)
{
int _x,
_y,
_z;
size_t i,
start = 0;
double real_size = 0.0,
real_scale = 1.0;
LaserBoy_3D_double real_min = DBL_MAX,
real_max = -DBL_MAX,
real_offset = 0.0;
if(ignore_origin)
start = 2;
for(i = start; i < size(); i++) // ignore the origin vector
{
if(at(i).x > real_max.x) real_max.x = at(i).x;
if(at(i).x < real_min.x) real_min.x = at(i).x;
if(at(i).y > real_max.y) real_max.y = at(i).y;
if(at(i).y < real_min.y) real_min.y = at(i).y;
if(at(i).z > real_max.z) real_max.z = at(i).z;
if(at(i).z < real_min.z) real_min.z = at(i).z;
}
real_offset.x = (real_max.x - ((real_max.x - real_min.x) / 2));
real_offset.y = (real_max.y - ((real_max.y - real_min.y) / 2));
real_offset.z = (real_max.z - ((real_max.z - real_min.z) / 2));
if(fabs(real_max.x - real_min.x) > real_size)
real_size = fabs(real_max.x - real_min.x);
if(fabs(real_max.y - real_min.y) > real_size)
real_size = fabs(real_max.y - real_min.y);
if(fabs(real_max.z - real_min.z) > real_size)
real_size = fabs(real_max.z - real_min.z);
real_scale = 65535.0 / real_size;
//----------------------------------------------------------------
for(i = start; i < size(); i++) // ignore the origin vector
{
_x = (int)round((at(i).x - real_offset.x) * real_scale);
_y = (int)round((at(i).y - real_offset.y) * real_scale);
_z = (int)round((at(i).z - real_offset.z) * real_scale);
if(_x > 32767) _x = 32767;
if(_x < -32767) _x = -32767;
if(_y > 32767) _y = 32767;
if(_y < -32767) _y = -32767;
if(_z > 32767) _z = 32767;
if(_z < -32767) _z = -32767;
at(i).x = (double)(_x);
at(i).y = (double)(_y);
at(i).z = (double)(_z);
}
}
//--------------------------------------------------------------------
return;
}
//############################################################################
void LaserBoy_real_segment::normalize_vectors_with_origin(bool ignore_origin)
{
if(size() > 2)
{
int _x,
_y,
_z;
size_t i,
start = 0;
double real_size = 0.0,
real_scale = 1.0;
LaserBoy_3D_double real_min = DBL_MAX,
real_max = -DBL_MAX;
if(ignore_origin)
start = 2;
for(i = start; i < size(); i++) // ignore the origin vector
{
if(at(i).x > real_max.x) real_max.x = at(i).x;
if(at(i).x < real_min.x) real_min.x = at(i).x;
if(at(i).y > real_max.y) real_max.y = at(i).y;
if(at(i).y < real_min.y) real_min.y = at(i).y;
if(at(i).z > real_max.z) real_max.z = at(i).z;
if(at(i).z < real_min.z) real_min.z = at(i).z;
}
if(fabs(real_max.x) > real_size)
real_size = fabs(real_max.x);
if(fabs(real_min.x) > real_size)
real_size = fabs(real_min.x);
if(fabs(real_max.y) > real_size)
real_size = fabs(real_max.y);
if(fabs(real_min.y) > real_size)
real_size = fabs(real_min.y);
if(fabs(real_max.z) > real_size)
real_size = fabs(real_max.z);
if(fabs(real_min.z) > real_size)
real_size = fabs(real_min.z);
real_size *= 2;
real_scale = 65535.0 / real_size;
//----------------------------------------------------------------
for(i = start; i < size(); i++) // ignore the origin vector
{
_x = (int)round((at(i).x) * real_scale);
_y = (int)round((at(i).y) * real_scale);
_z = (int)round((at(i).z) * real_scale);
if(_x > 32767) _x = 32767;
if(_x < -32767) _x = -32767;
if(_y > 32767) _y = 32767;
if(_y < -32767) _y = -32767;
if(_z > 32767) _z = 32767;
if(_z < -32767) _z = -32767;
at(i).x = (double)(_x);
at(i).y = (double)(_y);
at(i).z = (double)(_z);
}
}
//--------------------------------------------------------------------
return;
}
//############################################################################
void LaserBoy_real_segment::to_unit(bool ignore_origin)
{
if(size() > 2)
{
size_t i,
start = 0;
double real_size = 0.0,
real_scale = 1.0;
LaserBoy_3D_double real_min = DBL_MAX,
real_max = -DBL_MAX,
real_offset = 0.0;
if(ignore_origin)
start = 2;
for(i = start; i < size(); i++) // ignore the origin vector
{
if(at(i).x > real_max.x) real_max.x = at(i).x;
if(at(i).x < real_min.x) real_min.x = at(i).x;
if(at(i).y > real_max.y) real_max.y = at(i).y;
if(at(i).y < real_min.y) real_min.y = at(i).y;
if(at(i).z > real_max.z) real_max.z = at(i).z;
if(at(i).z < real_min.z) real_min.z = at(i).z;
}
real_offset.x = (real_max.x - ((real_max.x - real_min.x) / 2));
real_offset.y = (real_max.y - ((real_max.y - real_min.y) / 2));
real_offset.z = (real_max.z - ((real_max.z - real_min.z) / 2));
if(fabs(real_max.x - real_min.x) > real_size)
real_size = fabs(real_max.x - real_min.x);
if(fabs(real_max.y - real_min.y) > real_size)
real_size = fabs(real_max.y - real_min.y);
if(fabs(real_max.z - real_min.z) > real_size)
real_size = fabs(real_max.z - real_min.z);
real_scale = 2.0 / real_size;
//----------------------------------------------------------------
for(i = start; i < size(); i++) // ignore the origin vector
at(i) = (at(i) - real_offset) * real_scale;
}
//--------------------------------------------------------------------
return;
}
//############################################################################
void LaserBoy_real_segment::to_unit_with_origin(bool ignore_origin)
{
if(size() > 2)
{
size_t i,
start = 0;
double real_size = 0.0,
real_scale = 1.0;
LaserBoy_3D_double real_min = DBL_MAX,
real_max = -DBL_MAX;
if(ignore_origin)
start = 2;
for(i = start; i < size(); i++) // ignore the origin vector
{
if(at(i).x > real_max.x) real_max.x = at(i).x;
if(at(i).x < real_min.x) real_min.x = at(i).x;
if(at(i).y > real_max.y) real_max.y = at(i).y;
if(at(i).y < real_min.y) real_min.y = at(i).y;
if(at(i).z > real_max.z) real_max.z = at(i).z;
if(at(i).z < real_min.z) real_min.z = at(i).z;
}
if(fabs(real_max.x) > real_size)
real_size = fabs(real_max.x);
if(fabs(real_min.x) > real_size)
real_size = fabs(real_min.x);
if(fabs(real_max.y) > real_size)
real_size = fabs(real_max.y);
if(fabs(real_min.y) > real_size)
real_size = fabs(real_min.y);
if(fabs(real_max.z) > real_size)
real_size = fabs(real_max.z);
if(fabs(real_min.z) > real_size)
real_size = fabs(real_min.z);
real_size *= 2;
real_scale = 2.0 / real_size;
//----------------------------------------------------------------
for(i = start; i < size(); i++) // ignore the origin vector
at(i) *= real_scale;
}
//--------------------------------------------------------------------
return;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::clip(const LaserBoy_3D_double& max,
const LaserBoy_3D_double& min,
const double& granularity
)
{
if(size() > 1)
{
LaserBoy_real_segment clipped;
LaserBoy_3D_double c1,
c2;
LaserBoy_real_vertex blank;
//----------------------------------------------------------------
if(clip_check(max, min) == false)
{
clear();
return *this;
}
//----------------------------------------------------------------
clipped.palette_index = palette_index;
reduce_blank_vectors();
if(LaserBoy_bounds_check(at(0), max, min)) // 0 is in bounds
{
switch(clip_vector(at(0), at(1), max, min, granularity, c1, c2))
{
case no_line:
clipped.push_back(blank);
break;
case p1_in_p2_in: // not possible
case p1_in_p2_out:
clipped.push_back(at(0));
break;
case p1_out_p2_in:
case p1_out_p2_out:
clipped.push_back(at(0));
clipped.back() = c1;
break;
}
}
else
clipped.push_back(at(0));
for(size_t i = 1; i < size(); i++)
{
if(LaserBoy_bounds_check(at(i - 1), max, min) || LaserBoy_bounds_check(at(i), max, min))
{
switch(clip_vector(at(i - 1), at(i), max, min, granularity, c1, c2))
{
case no_line:
clipped.push_back(blank);
break;
case p1_in_p2_in: // not possible
clipped.push_back(at(i));
break;
case p1_in_p2_out:
clipped.push_back(at(i));
clipped.back() = c2;
break;
case p1_out_p2_in:
clipped.push_back(blank);
clipped.back() = c1;
clipped.push_back(at(i));
break;
case p1_out_p2_out:
clipped.push_back(blank);
if(at(i).is_lit())
{
clipped.back() = c1;
clipped.push_back(at(i));
clipped.back() = c2;
}
break;
}
} // if(LaserBoy_bounds_check(at(i - 1), max, min) || LaserBoy_bounds_check(at(i), max, min))
else // at(i - 1) and at(i) are both in bounds
clipped.push_back(at(i));
} // end for(size_t i = 1; i < size(); i++)
clipped.reduce_blank_vectors();
if(clipped.size() > 1)
*this = clipped;
else
clear();
return *this;
} // end if(size() > 1)
clear();
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::clip()
{
return clip(LaserBoy_3D_double( 32767.0, 32767.0, 32767.0), // max
LaserBoy_3D_double(-32767.0, -32767.0, -32767.0), // min
65536.0 // granularity
);
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::clip_around_coordinate(const LaserBoy_3D_double& center,
const LaserBoy_3D_double& max,
const LaserBoy_3D_double& min,
const double& granularity
)
{
LaserBoy_real_segment rs(*this);
if(size() > 1)
{
rs.clip(max + center, min + center, granularity);
rs -= center;
*this = rs;
}
return *this;
}
//############################################################################
LaserBoy_real_segment& LaserBoy_real_segment::clip_around_coordinate(const LaserBoy_3D_double& center,
const double range,
const double& granularity
)
{
LaserBoy_real_segment rs(*this);
if(size() > 1)
{
rs.clip(LaserBoy_3D_double( range + center.x, range + center.y, range + center.z),
LaserBoy_3D_double(-range + center.x, -range + center.y, -range + center.z),
granularity
);
rs -= center;
*this = rs;
}
return *this;
}
//############################################################################
//////////////////////////////////////////////////////////////////////////////
//############################################################################