Cc3dVector4 componentProduct(const Cc3dVector4&v1,const Cc3dVector4&v2){
    Cc3dVector4 v(v1.x()*v2.x(),
                             v1.y()*v2.y(),
                             v1.z()*v2.z(),
                             v1.w()*v2.w());
    return v;
}
Cc3dVector4 cross(const Cc3dVector4&v1,const Cc3dVector4&v2)
{
    assert(v1.w()==0);
    assert(v2.w()==0);
    Cc3dVector4 rs(v1.y()*v2.z()-v1.z()*v2.y(),
                   v1.z()*v2.x()-v1.x()*v2.z(),
                   v1.x()*v2.y()-v1.y()*v2.x(),
                   0);//cross product result must be a vector, so the fourth component set to zero
    return rs;
}
float getLength2(const Cc3dVector4&v){//square of length
    assert(v.w()==0);
    return v.x()*v.x()+v.y()*v.y()+v.z()*v.z();
}
float getLength(const Cc3dVector4&v){
    assert(v.w()==0);
    return sqrtf(v.x()*v.x()+v.y()*v.y()+v.z()*v.z());
}
Cc3dVector4 Cc3dVector4::operator -(const Cc3dVector4&right)const {
    Cc3dVector4 rs(this->x()-right.x(),this->y()-right.y(),this->z()-right.z(),this->w()-right.w());
    return rs;
}